Skip to content

Initial core bot activity library, CI, and extensibility#227

Draft
rido-min wants to merge 76 commits intomainfrom
next/core
Draft

Initial core bot activity library, CI, and extensibility#227
rido-min wants to merge 76 commits intomainfrom
next/core

Conversation

@rido-min
Copy link
Member

This pull request introduces the foundational structure for the new Microsoft.Bot.Core library, establishing core activity and schema types, build configuration, and initial unit tests. The changes set up the basic serialization/deserialization logic for bot activities, extensibility for custom properties, and the CI workflow for automated builds and tests.

Core Library and Schema Implementation:

  • Added the initial implementation of the CoreActivity class and supporting schema types (ActivityTypes, ChannelData, Conversation, ConversationAccount, and extensibility for additional properties) in the Microsoft.Bot.Core.Schema namespace, including JSON serialization/deserialization logic and reply creation methods. [1] [2] [3] [4] [5]
  • Introduced a placeholder for AddBotApplication in Hosting for future extensibility.

Build and Solution Configuration:

  • Added core.slnx solution file referencing the main project, unit test project, and solution items for centralized configuration.
  • Established common build properties and targets in Directory.Build.props and Directory.Build.targets, including code analysis, documentation, and versioning with Nerdbank.GitVersioning. [1] [2]
  • Configured the main project (Microsoft.Bot.Core.csproj) to target both .NET 8 and .NET 10, with appropriate package references for authentication and identity.

Continuous Integration:

  • Introduced a GitHub Actions workflow (core-ci.yaml) for building and testing the core library on push and pull requests to the next/core branch.

Unit Testing:

  • Added a unit test project (Microsoft.Bot.Core.UnitTests) with dependencies on xUnit and coverlet for code coverage, and a test suite validating extensibility and serialization/deserialization of custom activity types. [1] [2]Add .NET solution for extensible bot activity schemas with modern serialization, extension data, and reply support. Includes CI workflow, semantic versioning, and comprehensive unit tests for schema evolution and custom fields.

Add .NET solution for extensible bot activity schemas with modern serialization, extension data, and reply support. Includes CI workflow, semantic versioning, and comprehensive unit tests for schema evolution and custom fields.
Added a permissions section to the Core-CI workflow, granting read access to repository contents and write access to pull-requests. This explicitly defines the workflow's required permissions.
/// </summary>
public static readonly JsonSerializerOptions DefaultJsonOptions = new()
{
WriteIndented = true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting this at the bottom most layer means that more space will be used up in the payload

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but not too much. I think it's ok for now

/// The reply activity automatically swaps the From and Recipient accounts and preserves
/// the conversation context, channel ID, and service URL from the original activity.
/// </remarks>
public CoreActivity CreateReplyActivity(string text = "")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a note: Should this exist here or be in the client layer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a new optional param to set the type

rido-min and others added 2 commits December 10, 2025 15:00
This pull request introduces several new sample bots and supporting
infrastructure to the `core` directory, demonstrating different usage
scenarios for the Microsoft.Bot.Core SDK. It also adds compatibility
support for legacy Bot Framework bots, improves development environment
configuration, and updates documentation and gitignore settings.

**New sample bots and scenarios:**

- Added three new sample projects:
-
[`CompatBot`](diffhunk://#diff-22411d9bef78e3d139f1e4b1a4d5e047bb26428a97bf59df7f5b983e584babd8R1-R13):
Demonstrates running a legacy Bot Framework bot using the new
compatibility layer, including `EchoBot` implementation and required
configuration files.
[[1]](diffhunk://#diff-22411d9bef78e3d139f1e4b1a4d5e047bb26428a97bf59df7f5b983e584babd8R1-R13)
[[2]](diffhunk://#diff-b9be640e365d9187b0d1a2021dddb84311b737f8c28b16428e3b2a450a4f331aR1-R35)
[[3]](diffhunk://#diff-62be1f70aaabb519334fe39cd50c0e25a98717ebb9fab85b688832917c9c75bbR1-R29)
[[4]](diffhunk://#diff-834a6cbae004839d32944b2f2a3cf8edc3a32f558597d464401178fa95781edcR1-R9)
-
[`CoreBot`](diffhunk://#diff-1087baf076a83b00d0c97ef01c02174668cb26c9fad5d2c33284e0889150ed65R1-R13):
Shows a simple bot using the new SDK, with configuration and logging
settings.
[[1]](diffhunk://#diff-1087baf076a83b00d0c97ef01c02174668cb26c9fad5d2c33284e0889150ed65R1-R13)
[[2]](diffhunk://#diff-b94b53965e9052345453f2ab6bec21420a36c4b67c9a6c568b9c80edcd0882d1R1-R22)
[[3]](diffhunk://#diff-84b21a8c78e12fee4df3b2d67483407632a1fe5d25691ed7cfefde85adc92a25R1-R11)
-
[`Proactive`](diffhunk://#diff-ffe34fac742569e7a6cfb5589871a8b9571c7692f6af33e167f39cc2b8be3ed3R1-R17):
Demonstrates sending proactive messages using a background worker.
[[1]](diffhunk://#diff-ffe34fac742569e7a6cfb5589871a8b9571c7692f6af33e167f39cc2b8be3ed3R1-R17)
[[2]](diffhunk://#diff-f32e1fd30a40c5aa42855895485dbb9c8b79d4029cd3db1a1446f48846f8604dR1-R10)
[[3]](diffhunk://#diff-61d7e83f772e536a1729f5c12b1b028a2a396a28e2175541489e85d89d2758ecR1-R31)
[[4]](diffhunk://#diff-1342c159b3ce809afd5880d58bd2f17e3eeade347f10d5b8d6d550cb3a0ab8f9R1-R8)
- Added scenario scripts for middleware and proactive messaging,
runnable via dotnet script.
[[1]](diffhunk://#diff-aee4a2e56fbce4adfe46afec84a447a9aab7752f7c24982b51b8475af942124fR1-R34)
[[2]](diffhunk://#diff-8287e53b5a4e259703b929262b11fdb5f783564de364cc184d27a5b7486de729R1-R43)
- Provided an example `launchSettings.json` for local development of
scenarios.

**Compatibility support:**

- Introduced `CompatAdapter` and related classes to bridge new bot
application models with legacy Bot Framework interfaces, enabling easier
migration and integration of existing bots.
[[1]](diffhunk://#diff-ee802b583e856949e14f231284969979f8827efaa484f0b431badb7936809855R1-R116)
[[2]](diffhunk://#diff-e70e201729b0f386ddb70a5d3f83751f2bd0a08e527b0a5265fbb8094a9abe19R1-R27)

**Development environment and documentation improvements:**

- Updated `.devcontainer/devcontainer.json` to add Docker-in-Docker,
.NET 10, and ensure latest feature versions for improved local
development experience.
- Added a `README.md` with instructions for testing and running
scenarios.
- Added common development files to `.gitignore` and included it in the
solution.
[[1]](diffhunk://#diff-af85f59c6492668dca14d5f06b54cc2c3173708c83073e1d947b4c007dc851d6R1-R2)
[[2]](diffhunk://#diff-19ad97af5c1b7109a9c62f830310091f393489def210b9ec1ffce152b8bf958cR4-R12)

**Solution structure updates:**

- Updated `core.slnx` to include new sample projects and `.gitignore` as
solution items.

---

**New sample bots and scenarios:**
- Added `CompatBot`, `CoreBot`, and `Proactive` sample projects with
implementations and configuration files to demonstrate different SDK
usage scenarios.
[[1]](diffhunk://#diff-22411d9bef78e3d139f1e4b1a4d5e047bb26428a97bf59df7f5b983e584babd8R1-R13)
[[2]](diffhunk://#diff-b9be640e365d9187b0d1a2021dddb84311b737f8c28b16428e3b2a450a4f331aR1-R35)
[[3]](diffhunk://#diff-62be1f70aaabb519334fe39cd50c0e25a98717ebb9fab85b688832917c9c75bbR1-R29)
[[4]](diffhunk://#diff-834a6cbae004839d32944b2f2a3cf8edc3a32f558597d464401178fa95781edcR1-R9)
[[5]](diffhunk://#diff-1087baf076a83b00d0c97ef01c02174668cb26c9fad5d2c33284e0889150ed65R1-R13)
[[6]](diffhunk://#diff-b94b53965e9052345453f2ab6bec21420a36c4b67c9a6c568b9c80edcd0882d1R1-R22)
[[7]](diffhunk://#diff-84b21a8c78e12fee4df3b2d67483407632a1fe5d25691ed7cfefde85adc92a25R1-R11)
[[8]](diffhunk://#diff-ffe34fac742569e7a6cfb5589871a8b9571c7692f6af33e167f39cc2b8be3ed3R1-R17)
[[9]](diffhunk://#diff-f32e1fd30a40c5aa42855895485dbb9c8b79d4029cd3db1a1446f48846f8604dR1-R10)
[[10]](diffhunk://#diff-61d7e83f772e536a1729f5c12b1b028a2a396a28e2175541489e85d89d2758ecR1-R31)
[[11]](diffhunk://#diff-1342c159b3ce809afd5880d58bd2f17e3eeade347f10d5b8d6d550cb3a0ab8f9R1-R8)
- Added scenario scripts for middleware and proactive messaging, plus an
example launch settings file for local testing.
[[1]](diffhunk://#diff-aee4a2e56fbce4adfe46afec84a447a9aab7752f7c24982b51b8475af942124fR1-R34)
[[2]](diffhunk://#diff-8287e53b5a4e259703b929262b11fdb5f783564de364cc184d27a5b7486de729R1-R43)
[[3]](diffhunk://#diff-19cd1809f42bd0d871748a1e3bf7c705961f9abd0a4da67acc547f42c1ebfcd6R1-R20)

**Compatibility support:**
- Introduced `CompatAdapter` and `CompatActivity` to support running
legacy Bot Framework bots with the new SDK.
[[1]](diffhunk://#diff-ee802b583e856949e14f231284969979f8827efaa484f0b431badb7936809855R1-R116)
[[2]](diffhunk://#diff-e70e201729b0f386ddb70a5d3f83751f2bd0a08e527b0a5265fbb8094a9abe19R1-R27)

**Development environment and documentation:**
- Enhanced `.devcontainer` with Docker-in-Docker, .NET 10, and latest
feature versions for improved local development.
- Added a `README.md` with setup and testing instructions.
- Updated `.gitignore` and included it in the solution for better source
control hygiene.
[[1]](diffhunk://#diff-af85f59c6492668dca14d5f06b54cc2c3173708c83073e1d947b4c007dc851d6R1-R2)
[[2]](diffhunk://#diff-19ad97af5c1b7109a9c62f830310091f393489def210b9ec1ffce152b8bf958cR4-R12)

**Solution structure:**
- Updated `core.slnx` to include new projects and configuration files.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rido-min <14916339+rido-min@users.noreply.github.com>
@rido-min rido-min added the CORE label Dec 11, 2025
rido-min and others added 22 commits December 10, 2025 17:46
Updated Azure DevOps pipeline to trigger only on next/* branches and use ubuntu-22.04. Added cd-core.yaml to solution items in core.slnx. Removed null-forgiving operator from CoreActivity.cs return statement for safer null handling.
Added a UseDotNet@2 task to install .NET 8 SDK (8.0.x) before the .NET 10 SDK in the BuildTestPack job. This ensures both SDK versions are available for build and test processes.
Changed package icon to bot_icon.png in project properties. Added ItemGroup to explicitly include bot_icon.png and README.md at the root of the NuGet package during packing.
Added a new bot_icon.png file to the project, providing a graphical asset that can be used as an icon or visual element within the application.
Changed the pipeline condition so that NuGet packages are pushed only when building from the refs/heads/next/core branch, instead of the main branch. This restricts package publishing to the next/core branch.
Ignored launchSettings.json, appsettings.Development.json, and .runsettings to prevent tracking of local configuration and test settings files.
Introduce Microsoft.Bot.Core.Tests targeting .NET 10.0 with xUnit and code coverage. Add core-test.yaml workflow to run these tests with Azure AD credentials. Update solution file to include new test project and workflow. Implement ConversationClientTest for Teams activity scenarios. Update core-ci.yaml to run only unit tests.
Updated the build pipeline to run tests only for the Microsoft.Bot.Core.UnitTests project. Changed environment variable to "TEST_CONVERSATIONID" in ConversationClientTest.cs and corrected the hardcoded conversation ID format by removing the message ID suffix.
- Prefix echo replies with "Echo from BF Compat"
- Change default log level to Warning; add Debug for Microsoft.Bot
- Remove using statement for TurnContext in CompatAdapter
- Expand exception handling to rethrow non-HttpOperationException
- Add debug/info logging to BotApplication activity processing
Introduce .editorconfig for code style and nullable strictness. Update solution to include .editorconfig. Rename CoreActivity.CreateReplyActivity to CreateReplyMessageActivity and update all usages. Extend CoreActivityJsonContext for Int64/Double support. Apply minor formatting fixes and missing braces. Strengthen and update unit tests for new property types and method changes.
Replaced all var declarations with explicit types across the codebase, including tests, bot implementations, and entry points. This improves code clarity and type safety, making variable types more visible and aiding maintainability. No functional changes were made.
Added copyright and MIT license headers to all source and test files.
Updated .editorconfig to enforce file header template for new files.
Made minor code style improvements and access modifier updates. Ensured
consistent attribution and licensing across the codebase.
EchoBot now informs users how to trigger a proactive message via a new `/api/notify/{conversationId}` endpoint. Added a GET endpoint to send proactive messages to a conversation by ID. Updated message handling to support CancellationToken and included necessary usings for proactive messaging support.
Integrate Azure Monitor Application Insights telemetry into both
CompatBot and CoreBot using OpenTelemetry. Update appsettings.json to
include a placeholder Application Insights connection string and adjust
logging levels for better diagnostics. Refactor EchoBot to accept an
ILogger and log version info; comment out some unused message handlers.
Improve CoreBot reply robustness by safely extracting conversation type.
Reformat project files for consistency and explicitly add Azure Monitor
package. Update Proactive Worker to use constants for ServiceUrl and
FromId. Refactor ConversationClient to use StringContent for activity
payloads, ensuring correct JSON serialization and content type.
Removed unnecessary using directives from EchoBot.cs and ConversationClient.cs. Updated TryGetValue in Program.cs to use object? for better type safety and clarity.
Refactored pipeline triggers to use path filters for PRs, targeting only core/** changes. Removed obsolete trigger config and comments. Introduced PushToADOFeed variable to control NuGet push step, replacing branch-based condition.
rido-min and others added 6 commits January 23, 2026 08:42
This pull request refactors the `CompatAdapter` and related middleware
to use dependency injection for service resolution, improving
maintainability and aligning with modern .NET practices. The main
changes involve replacing constructor parameters with
`IServiceProvider`, updating middleware to resolve dependencies, and
enhancing logging in the `CompatBotAdapter`.

**Dependency Injection Refactoring:**

* `CompatAdapter` now receives an `IServiceProvider` in its constructor,
and uses it to resolve `TeamsBotApplication` and `CompatBotAdapter`
instead of receiving them directly as parameters. All usages of these
services within the class have been updated accordingly.
* `CompatAdapterMiddleware` now receives both the Bot Framework
middleware and an `IServiceProvider`, enabling it to resolve required
services such as `IHttpContextAccessor` and `ILogger`.

**Middleware and Adapter Updates:**

* Middleware instantiation in `CompatAdapter` is updated to pass the
`IServiceProvider` to each `CompatAdapterMiddleware`, ensuring
dependencies are available during middleware execution.
* Within `CompatAdapterMiddleware`, the `CompatBotAdapter` is now
constructed with resolved `IHttpContextAccessor` and `ILogger`
instances, improving logging and context-awareness.

**Logging Improvements:**

* Enhanced logging in `CompatBotAdapter` to include HTTP status codes
when sending invoke responses, and to avoid serialization if the
response body is null.

**General Code Modernization:**

* Added missing `using` statements for dependency injection and logging
namespaces in affected files.
[[1]](diffhunk://#diff-e6d701ce121dda6651c0dea00498d45e2cc0b0cec446a578f3058be691c7c0f5R8)
[[2]](diffhunk://#diff-80a974c881b9ff3a697fe5b07985c8f55edb2e2896384d6d437a3e8dfa5a2817R5-R6)
The CompatMiddlware Adapter was creating a new TurnContext, and that
created problems with Middleware.

Instead of trying to adapt the middlware, we can just run the BF
Middleware pipeline
This pull request refactors and improves the bot application hosting and
authentication pipeline. The main goals are to defer configuration
reading until the service provider is built, avoid building the service
provider during service registration (an anti-pattern), and improve
logging flexibility and reliability. New options classes are introduced
to cleanly pass configuration, and authentication/authorization
registration is made safer and more robust.

Key changes include:

**Configuration and Options Refactoring:**

* Introduced `BotClientOptions` and `AuthenticationSchemeOptions`
classes to encapsulate bot client and authentication scheme
configuration, deferring configuration reading until the service
provider is available.
[[1]](diffhunk://#diff-65196a45c43063ad64be1ce1c69cd1cf0ddcc2f8b999b5679d74bb6d4a610ff0R1-R20)
[[2]](diffhunk://#diff-13be7f71b9314c04c36d3d24e99723628e236cfc008159b22f6d9a862f8c75e0R1-R20)
* Refactored `AddTeamsBotApplication` and `AddBotClient<TClient>` to
register options and avoid building the service provider during
registration, using `AddOptions<T>().Configure<IConfiguration>()`
instead.
[[1]](diffhunk://#diff-a5c655bf5836d61efb23de5aba33c6dc81b61cabaf9341f68c9f2a28afc48b58L26-R47)
[[2]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L96-R163)
* Updated MSAL configuration to pass the logger as a parameter and
select configuration and logger from service descriptors if available,
only building a temporary provider as a fallback.

**Authentication and Authorization Pipeline:**

* Refactored `AddAuthorization` to accept an optional logger and to
select configuration and logger from service descriptors, only building
a temporary provider if necessary.
* Improved JWT Bearer authentication to resolve the logger from request
services at runtime, ensuring correct logging context and using a
`NullLogger` fallback.
[[1]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L106-R121)
[[2]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L127-R156)
[[3]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L145-R166)
[[4]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L156-R177)

**Middleware and Endpoint Registration:**

* Changed `UseBotApplication<TApp>` to operate on
`IEndpointRouteBuilder` instead of `IApplicationBuilder`, improving
flexibility and ensuring authentication/authorization middleware is
added safely.

**Logging Improvements:**

* Ensured that loggers are created from `ILoggerFactory` if available,
otherwise defaulting to `NullLogger`, and that logging is robust
throughout the authentication and configuration process.
[[1]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L65-R81)
[[2]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L75-R102)
[[3]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L127-R156)

**General Code Quality:**

* Added missing `using` directives for LINQ and other dependencies.
[[1]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7R4-R10)
[[2]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70R5)

These changes collectively improve the reliability, maintainability, and
testability of the bot application hosting and authentication
infrastructure.

---

**Configuration and Options Refactoring:**

- Introduced `BotClientOptions` and `AuthenticationSchemeOptions`
classes for encapsulating bot client and authentication scheme
configuration, deferring configuration reading until the service
provider is available.
[[1]](diffhunk://#diff-65196a45c43063ad64be1ce1c69cd1cf0ddcc2f8b999b5679d74bb6d4a610ff0R1-R20)
[[2]](diffhunk://#diff-13be7f71b9314c04c36d3d24e99723628e236cfc008159b22f6d9a862f8c75e0R1-R20)
- Refactored `AddTeamsBotApplication` and `AddBotClient<TClient>` to use
options registration and avoid building the service provider during
registration.
[[1]](diffhunk://#diff-a5c655bf5836d61efb23de5aba33c6dc81b61cabaf9341f68c9f2a28afc48b58L26-R47)
[[2]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L96-R163)
- Updated MSAL configuration to pass the logger as a parameter and to
select configuration/logger from service descriptors, only building a
temporary provider if necessary.

**Authentication and Authorization Pipeline:**

- Refactored `AddAuthorization` to accept an optional logger, select
configuration/logger from service descriptors, and only build a
temporary provider as a fallback.
- Improved JWT Bearer authentication to resolve the logger from request
services at runtime and use a `NullLogger` fallback, ensuring robust
logging.
[[1]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L106-R121)
[[2]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L127-R156)
[[3]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L145-R166)
[[4]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L156-R177)

**Middleware and Endpoint Registration:**

- Changed `UseBotApplication<TApp>` to work with `IEndpointRouteBuilder`
instead of `IApplicationBuilder`, ensuring authentication/authorization
middleware is added correctly and improving endpoint mapping
flexibility.

**Logging Improvements:**

- Ensured loggers are created from `ILoggerFactory` when available,
otherwise using a `NullLogger`, and improved logging reliability
throughout the configuration and authentication process.
[[1]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L65-R81)
[[2]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L75-R102)
[[3]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L127-R156)

**General Code Quality:**

- Added missing `using` directives for LINQ and other dependencies.
[[1]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7R4-R10)
[[2]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70R5)
**Key changes:**

**Activity Handler Extensions and Delegates**
- Added new handler delegates and extension methods for message update,
message delete, and message reaction activities (`OnMessageUpdate`,
`OnMessageDelete`, `OnMessageReaction`, `OnMessageReactionAdded`,
`OnMessageReactionRemoved`), enabling straightforward registration of
handlers for these Teams activity types.
- Refactored the invoke handler to use a strongly-typed
`Context<InvokeActivity>` and provided an `OnInvoke` extension method
for registering invoke handlers.

**Routing Infrastructure Enhancements**
- Updated the `Route` and `Router` classes to support handler functions
that can return a response (`HandlerWithReturn`) and added the
`InvokeRouteWithReturn` and `DispatchWithReturnAsync` methods to enable
this.
- Changed route matching logic to use the `TeamsActivityType` string for
more precise activity type matching.

---------

Co-authored-by: Rido <rido-min@users.noreply.github.com>
Revert the Microsoft.Bot.Builder.Integration.AspNet.Core NuGet package
version in Microsoft.Teams.Bot.Compat.csproj from 4.23.1 to 4.22.3. No
other changes were made.

---------

Co-authored-by: Kavin Singh <kavinsingh@microsoft.com>
rido-min and others added 19 commits February 2, 2026 07:24
## Summary

Refactored and expanded CompatActivityTests to provide comprehensive
coverage of the `FromCompatActivity()` method,
  including support for complex `SuggestedActions` payloads.

## Changes

### Test Structure:
- Refactored into component-based tests (12 total) organized by Activity
aspect:
    - Core Properties (2 tests)
    - Attachments (2 tests)
    - Entities (2 tests)
    - SuggestedActions (2 tests)
    - ChannelData (2 tests)
    - Integration/Round-trip (2 tests)
**Why?**
Makes it easier to mock the `CompatAdapter.ContinueConversationAsync`
method when testing. Without the interface, the class itself would first
have to be mocked, which means all the underlying components will have
to be configured by hand.
1. Keeps the same pattern as CloudAdapter
2. `TurnContext.Adapter` will reference the `CompatAdapter` and not just
the `CompatBotAdapter` as it was before this change. This means the same
adapter is used everywhere.
3. Updated `ContinueConversationAsync` to follow the implementation of
`BotAdapter`. I also ensure that our override is used even if the object
is typecast to `BotAdapter`. `BotAdapter.ContinueConversationAsync`
creates a brand new turn context without the underlying compat clients
which is not intended.
4. Removed `ICloudAdapter` because it is not needed anymore.
`BotAdapter` is an abstract class that allows easy mocking of the
CompatAdapter.
5. Without a separate `CompatBotAdapter` DI setup is simplified
…ng for multiple matching routes (#301)

- Introduced `ConversationUpdateActivity` and `InstallUpdateActivity` .
- Implemented handlers for conversation update (members added/removed,
channel created/deleted etc..) and installation update events in
`TeamsBot`.
- Added support for pattern-based and regex-based message handlers
(e.g., responding to "hello" or slash commands like `/help`).
- Added TeamsChannelBot, for Channel and Teams related testing
- Added warning logs if multiple routes match an activity
- Made names for handlers more specific so that warning logs are clear
- Added Router to hosting
- Removed deserialization methods for teams activities - we never read
from json strings
- Removed serialization methods for non msg/invoke activities - we only
send message activities
- Serialization for msg and invoke activities handled centrally be teams
activity class
- Simplified constructing activities from core activity
- Refactored TeamsChannelData to move small channel data specific
classes into same file
- Fixed duplication of conversation account
- Added TODOs for unverified properties/handlers and commented it for
now
- Moved tests for non msg activities to one file  (very few per class)
- Made DateTime - > string
This pull request introduces several improvements and refactorings
across the Teams bot codebase, focusing on simplifying property
management in conversation accounts, enhancing logging for
authentication and activity flows, and updating tests for agentic
identity support.

**TeamsConversationAccount property management:**

* Refactored `TeamsConversationAccount` to store all Teams-specific
properties in the `Properties` dictionary and provide strongly-typed
accessors for each property (e.g., `AadObjectId`, `GivenName`,
`Surname`, etc.), simplifying construction and property access.

**Logging enhancements:**

* Improved logging in `BotAuthenticationHandler` by raising log levels
for token acquisition events, and added trace-level logging to output
JWT token claims for better debugging.
[[1]](diffhunk://#diff-0d237734ffe42c3bd2a77d27777c6ffc86396b9db5cba4f26c22b41918d0384bL35-R40)
[[2]](diffhunk://#diff-0d237734ffe42c3bd2a77d27777c6ffc86396b9db5cba4f26c22b41918d0384bR58-R59)
[[3]](diffhunk://#diff-0d237734ffe42c3bd2a77d27777c6ffc86396b9db5cba4f26c22b41918d0384bR106-R123)
* Enhanced activity sending logs in `ConversationClient` to include the
destination URL and improved log message clarity.
* Updated startup logs in `BotApplication` to include the listener type
for better traceability.

**Test and configuration updates:**

* Updated unit tests in `TeamsActivityTests` to verify agentic identity
properties in the recipient, ensuring correct parsing and assignment.
* Added a local settings file to allow specific Bash commands for
building and testing in the `core/.claude/settings.local.json`.

**Other minor changes:**

* Cleaned up configuration code by removing outdated TODO comments about
making the MSAL instance configurable.
[[1]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L213)
[[2]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L244)
[[3]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L271)
* Fixed logger type in `TeamsBotApplication` constructor for
consistency.
* Minor formatting improvements in unit tests.
* Added missing `using` directive for JWT token handling.
* Removed redundant activity logging in `TeamsBotApplication`.
This pull request introduces several improvements and refactorings
across the Teams bot codebase, focusing on simplifying property
management in conversation accounts, enhancing logging for
authentication and activity flows, and updating tests for agentic
identity support.

**TeamsConversationAccount property management:**

* Refactored `TeamsConversationAccount` to store all Teams-specific
properties in the `Properties` dictionary and provide strongly-typed
accessors for each property (e.g., `AadObjectId`, `GivenName`,
`Surname`, etc.), simplifying construction and property access.

**Logging enhancements:**

* Improved logging in `BotAuthenticationHandler` by raising log levels
for token acquisition events, and added trace-level logging to output
JWT token claims for better debugging.
[[1]](diffhunk://#diff-0d237734ffe42c3bd2a77d27777c6ffc86396b9db5cba4f26c22b41918d0384bL35-R40)
[[2]](diffhunk://#diff-0d237734ffe42c3bd2a77d27777c6ffc86396b9db5cba4f26c22b41918d0384bR58-R59)
[[3]](diffhunk://#diff-0d237734ffe42c3bd2a77d27777c6ffc86396b9db5cba4f26c22b41918d0384bR106-R123)
* Enhanced activity sending logs in `ConversationClient` to include the
destination URL and improved log message clarity.
* Updated startup logs in `BotApplication` to include the listener type
for better traceability.

**Test and configuration updates:**

* Updated unit tests in `TeamsActivityTests` to verify agentic identity
properties in the recipient, ensuring correct parsing and assignment.
* Added a local settings file to allow specific Bash commands for
building and testing in the `core/.claude/settings.local.json`.

**Other minor changes:**

* Cleaned up configuration code by removing outdated TODO comments about
making the MSAL instance configurable.
[[1]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L213)
[[2]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L244)
[[3]](diffhunk://#diff-32c43eec964cc43a0cc857afbe1da981ec6000ac6c95c94aef469c4ce859ebe7L271)
* Fixed logger type in `TeamsBotApplication` constructor for
consistency.
* Minor formatting improvements in unit tests.
* Added missing `using` directive for JWT token handling.
* Removed redundant activity logging in `TeamsBotApplication`.
Expanded logging, builder arg support, improved middleware token
handling, new AddBotApplication overload, and upgraded NuGet packages
for authentication and identity.

This pull request introduces several improvements to the Teams bot
application framework, focusing on enhanced configuration flexibility,
improved dependency management, and minor code cleanups. The most
significant changes include updating method signatures to accept
command-line arguments, refining dependency injection patterns, and
updating package versions for better compatibility and security.

**Configuration and Dependency Injection Enhancements:**

* Changed `TeamsBotApplication.CreateBuilder` and
`TeamsBotApplicationBuilder` constructors to accept a `string[] args`
parameter, allowing applications to pass command-line arguments for more
flexible configuration. (`core/samples/TeamsBot/Program.cs`,
`core/samples/TeamsChannelBot/Program.cs`,
`core/src/Microsoft.Teams.Bot.Apps/TeamsBotApplication.cs`,
`core/src/Microsoft.Teams.Bot.Apps/TeamsBotApplicationBuilder.cs`)
[[1]](diffhunk://#diff-691809f7a90c5bda6ee5e4335c2c393864a32101545fb0b35c24bc659623361bL12-R12)
[[2]](diffhunk://#diff-42051fe23037cc0bf4fa811f899bd3e9cb86edb6178d1ff28bf63ac349db96a9L7-R7)
[[3]](diffhunk://#diff-e196e9ff5fcfc2368d02d38f06cf768e98cf7f8df31c730c799ca33def23a80eL82-R82)
[[4]](diffhunk://#diff-aafa3df8194fb624a2e49d4d9e6065209cbbc17844152cd6fd2e1edfcf7f9fe6L46-R48)
* Added a new `AddBotApplication` extension method to
`IServiceCollection` with a default configuration section name
("AzureAd"), simplifying bot application registration.
(`core/src/Microsoft.Teams.Bot.Core/Hosting/AddBotApplicationExtensions.cs`)

**Dependency Updates:**

* Updated package references in `Microsoft.Teams.Bot.Core.csproj` to
newer versions for `Microsoft.AspNetCore.Authentication.JwtBearer`,
`Microsoft.AspNetCore.Authentication.OpenIdConnect`, and
`Microsoft.Identity.Web` packages, improving compatibility and security.
(`core/src/Microsoft.Teams.Bot.Core/Microsoft.Teams.Bot.Core.csproj`)

**Code Quality and Cleanup:**

* Removed a pending suppress message attribute from the
`TeamsBotApplication` class, cleaning up unnecessary code annotations.
(`core/src/Microsoft.Teams.Bot.Apps/TeamsBotApplication.cs`)
* Updated variable names in the `CompatAdapter` to improve clarity and
consistency, and ensured cancellation tokens are propagated correctly.
(`core/src/Microsoft.Teams.Bot.Compat/CompatAdapter.cs`)

**Minor Configuration Update:**

* Changed logging configuration in `appsettings.json` to trace logs for
`Microsoft.Teams` instead of `Microsoft.Bot`, aligning logging with the
Teams bot framework. (`core/samples/CoreBot/appsettings.json`)
Seems our CI is broken because of
dotnet/sdk#53006

I use this opportunity to consolidate SuppressError messages.

This pull request refactors how code analysis suppressions are managed
across the solution. Instead of applying `[SuppressMessage]` attributes
directly to classes and methods, project-level suppressions are now
centralized in `GlobalSuppressions.cs` files for each relevant project.
This change improves maintainability and reduces clutter in the
codebase.

Key changes include:

**Centralization of Code Analysis Suppressions:**

* Added new `GlobalSuppressions.cs` files in `Microsoft.Teams.Bot.Core`,
`Microsoft.Teams.Bot.Apps`, and `Microsoft.Teams.Bot.Compat` projects to
house all project-level suppressions, including rules related to logging
performance and design guidelines.
[[1]](diffhunk://#diff-a31618c3543ca08086480902914d1b8a2662d91867b152f35a919465c3ac1623R1-R24)
[[2]](diffhunk://#diff-46bb45f0e912e49218b1f21c4aa2cdc301655c75a508bc71d8c2e1aa0691c9b4R1-R24)
[[3]](diffhunk://#diff-cee1e0aaa0d1fdbef17c0bb1c2b0a64fd3e6680a31c013f8c6b9a70d6fb8ad7bR1-R18)

**Removal of Inline SuppressMessage Attributes:**

* Removed `[SuppressMessage]` attributes from classes and methods in
files such as `Router.cs`, `TeamsApiClient.cs`, `CompatBotAdapter.cs`,
`BotApplication.cs`, `ConversationClient.cs`, `JwtExtensions.cs`,
`UserTokenClient.cs`, and `BotHttpClient.cs`, as well as from multiple
schema/activity/entity classes. These suppressions are now handled at
the project level.
[[1]](diffhunk://#diff-39661a1e6d086cf06cff19e9627a3424084ccb66df2254a6b56623ef4ccf5016L13-L14)
[[2]](diffhunk://#diff-a7b99b48404c7a1f8b81a59f20ace5e826e134eedaeda28dd38a0931db8c4c84L18)
[[3]](diffhunk://#diff-c443812ac75b10f0cb9e0929a1165dee72b7c96adbd232d830a65348ccd1b42bL25)
[[4]](diffhunk://#diff-2c89073290ce62fb61faed0da2a6153c8e93b318a57364fdbf4c3da6e440a436L16)
[[5]](diffhunk://#diff-d62a8ce4aac677906758eb430b84c9432f61ff95342701fdcae909310e2aed27L18)
[[6]](diffhunk://#diff-d3d44d1fb1f7c0af05be370ba32f80e12a136f7876e896ecf1a9facf97655c70L22)
[[7]](diffhunk://#diff-1943bfd92d68530022946c449fa60ec24a9032e9ad2bee4978ae0dc59bdc1739L24)
[[8]](diffhunk://#diff-44232a3c089c8de3dc8fdc228feebdda822293f4be104d00e28275525c46c8c2L19)
[[9]](diffhunk://#diff-44232a3c089c8de3dc8fdc228feebdda822293f4be104d00e28275525c46c8c2L38)
[[10]](diffhunk://#diff-44232a3c089c8de3dc8fdc228feebdda822293f4be104d00e28275525c46c8c2L70)
[[11]](diffhunk://#diff-44232a3c089c8de3dc8fdc228feebdda822293f4be104d00e28275525c46c8c2L101)
[[12]](diffhunk://#diff-44232a3c089c8de3dc8fdc228feebdda822293f4be104d00e28275525c46c8c2L124)
[[13]](diffhunk://#diff-b9fe8c2661f373312865c34021dcd68b97c7a7308d3814767e941a9e275212f4L13)
[[14]](diffhunk://#diff-f1c9ac72f51f1e74cdd25fd72f5b26a7ef64c41e998340dc92bf0c3501e4ee50L13)
[[15]](diffhunk://#diff-c012032b5d678f0c2c0adc3b209525719f308955fd766238e6f64ec324ca2c45L14)
[[16]](diffhunk://#diff-8fea9343e8aa50c65ec8c4a88b2040380b0b27da68735c7474bda5e7379e7456L11)

**Addition of New Suppression Rules:**

* Introduced a new suppression for `CA1054:URI-like parameters should
not be strings` in the `Microsoft.Teams.Bot.Core.Http` namespace, with
justification for consistency with existing API patterns.

These changes collectively make code analysis suppression more scalable
and easier to manage as the codebase evolves.
- Create Router internally with dedicated logger instead of injecting as
dependency

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* Added all invoke activities ( some are commented that could not be
tested )
* Added `AllInvokesBot` sample project for adaptive card actions, task
modules, file consent, and other invoke scenarios.
* Added `MessageExtensionBot` sample project.
* Made invoke activity and invoke response strongly typed vi generics.
- Refactored `CompatAdapter` to take in the required objects instead of
the service provider object, and then resolving them through it.
- Introduce `KeyedBotAuthenticationHandler` which configures auth based
on keyed configurations. Add MSAL configurations under a key, and use
that the instantiate this object and viola!
- Update incomming token validation to be based on keyed configurations
as well.
- As a consequence of the above changes, it is possible multiple keyed
instances of `TeamsBotApplication` and `CompatAdapter` allowing for
multiples apps to be hosted in a single process.
- Introduce PABot and CompatProactive samples, that test out PA
scenarios and proactive messaging scenarios, respectively.

**Testing**
- [x] PABot setup working
- [x] PABot EchoBot working
- [ ] PABot TeamsBot working
- [ ] CompatProactive working
- [x] Integration with PA codebase working

---------

Co-authored-by: Kavin Singh <kavinsingh@microsoft.com>
**Core SDK Enhancements:**

* Introduced `EventActivity` and `EventActivity<TValue>` classes to
represent event activities, including strongly-typed value payloads.
Also added `EventNames` constants for meeting event types.
* Defined strongly-typed value classes for meeting events:
`MeetingStartValue`, `MeetingEndValue`, `MeetingParticipantJoinValue`,
and `MeetingParticipantLeaveValue`, as well as related participant info
classes.
* Added `MeetingHandler.cs` with extension methods for registering
handlers for meeting start, end, participant join, and participant leave
events in `TeamsBotApplication`.

**Sample Bot and Documentation:**

* Added a new sample bot, `MeetingsBot`, including its project file,
implementation (`Program.cs`), configuration (`appsettings.json`), and a
detailed README explaining manifest requirements and Teams setup for
meeting events.
* Updated the solution file `core.slnx` to include the new `MeetingsBot`
sample.
Introduced ReplyToId property in CoreActivity and builder, enabling
reply tracking in activities. Updated ConversationClient to append
ReplyToId to outgoing URLs and adjusted "agents" channel ID truncation.
Simplified bot setup in Program.cs by removing telemetry and generic
parameters. Added a default route overload for UseBotApplication. Minor
logging and comment improvements.

This pull request introduces improvements to how reply handling is
managed in the bot framework, particularly around supporting and
propagating the `ReplyToId` property in activities. The changes ensure
that reply chains are correctly maintained and that conversation IDs are
truncated to the correct length for the 'agents' channel. Additionally,
the API for registering the bot application has been streamlined.

**Reply handling and activity schema improvements:**

* Added a `ReplyToId` property to the `CoreActivity` class, enabling
activities to specify which message they are replying to.
* Updated `CoreActivityBuilder` to set `ReplyToId` when copying from
another activity and added a `WithReplyToId` method for explicit
setting.
[[1]](diffhunk://#diff-5e00975e375bcb87e6b0d28d2367d865865a1254f089cfcab0d6abbb5db4be38R52-R56)
[[2]](diffhunk://#diff-5e00975e375bcb87e6b0d28d2367d865865a1254f089cfcab0d6abbb5db4be38R86-R96)

**Message sending and routing improvements:**

* Modified `SendActivityAsync` in `ConversationClient` to append
`ReplyToId` to the outgoing message URL if present, ensuring replies are
correctly threaded. Also, fixed conversation ID truncation for the
'agents' channel to a maximum of 100 characters (was 325).
* Added a new overload of `UseBotApplication` to simplify bot
application setup with a default route.

**Sample and registration cleanup:**

* Updated the sample bot (`CoreBot/Program.cs`) to use the new
`AddBotApplication` and `UseBotApplication` APIs, and cleaned up reply
message formatting.
## Summary

- Decoupling `IConfiguration` from the `TeamsBotApplication` and
`BotApplication` classes since it's not clear what configurations are
required.

## Test plan

- [x] Verify bot starts and logs the correct AppID at startup
- [x] Test with each config format: `MicrosoftAppId`, `CLIENT_ID`, and
`AzureAd:ClientId`
- [x] Confirm `BotApplicationOptions.AppId` defaults to empty string
when no config key is present

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
When setting up components manually BotApplicationOptions is probably
the least important argument. So it makes sense to make it optional.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
- All matching routes now run sequentially for non-invoke activities.
Previously only the first matching route executed, silently swallowing
any subsequent handlers.
   Registration order is preserved.
- Invoke routing remains first-match-wins. Invoke activities require
exactly one InvokeResponse back to Teams — running multiple handlers is
undefined behaviour.
- Startup throws if OnInvoke and specific invoke handlers are mixed.
Registering both OnInvoke and eg. OnAdaptiveCardAction guarantees one
response is silently swallowed. The valid approaches are: OnInvoke
exclusively with an internal if/else, or specific handlers exclusively.
- Startup throws if the same route is registered twice. Duplicate
registration is assumed to be a bug.
- Removed ILogger from Router. The logger passed was
ILogger<TeamsBotApplication>. Startup errors now throw
  exceptions instead of logging.
## No new features; focus is on code quality.


Explicit types replace var throughout for improved readability and
maintainability. Formatting and whitespace are standardized. Property
accessors use object? for nullability. Dependency injection and routing
use explicit types. Comments and documentation clarified. Minor bug
fixes and copyright headers updated.
This pull request primarily focuses on code cleanup and modernization
across several files, including improvements to copyright headers,
variable declarations, and import ordering. The changes help standardize
the codebase and make it more readable and maintainable.

**Copyright and Licensing Updates:**
* Updated copyright headers in `Route.cs` and `Router.cs` to remove "All
rights reserved" and ensure consistency with MIT licensing.
[[1]](diffhunk://#diff-770b878e7b1d580f51d38d08640ad9a37b9234dd9f80d1365738f44f225a8f56L1-R1)
[[2]](diffhunk://#diff-39661a1e6d086cf06cff19e9627a3424084ccb66df2254a6b56623ef4ccf5016L1-R3)
* Added proper copyright and licensing information to
`GlobalSuppressions.cs`.

**Code Style Improvements:**
* Replaced explicit variable declarations with type inference (e.g.,
`var` → `List<RouteBase>`) in `Router.cs` to improve readability and
clarity.
[[1]](diffhunk://#diff-39661a1e6d086cf06cff19e9627a3424084ccb66df2254a6b56623ef4ccf5016L65-R74)
[[2]](diffhunk://#diff-39661a1e6d086cf06cff19e9627a3424084ccb66df2254a6b56623ef4ccf5016L91-R92)
* Updated regex instantiation in `MessageHandler.cs` to use target-typed
`new` for conciseness.

**Import and Namespace Ordering:**
* Reordered and cleaned up using statements in `EchoBot.cs`,
`Program.cs`, and `SimpleGraphClient.cs` for better organization and
consistency.
[[1]](diffhunk://#diff-b9be640e365d9187b0d1a2021dddb84311b737f8c28b16428e3b2a450a4f331aL7-R13)
[[2]](diffhunk://#diff-62be1f70aaabb519334fe39cd50c0e25a98717ebb9fab85b688832917c9c75bbL6-R10)
[[3]](diffhunk://#diff-891dee2b4796177cac44609d7ec803a964633f9f214eb096a70aa612910c2ce6R10-L15)
* Removed unnecessary using statements in `Context.cs`.

**Type Safety Enhancements:**
* Improved type safety in `ConversationUpdateActivity.cs` by explicitly
specifying `object?` in property retrievals.
[[1]](diffhunk://#diff-8f9b05b82c5484251ba864fad6bd6ec711ff8b9d4ef23929c7122f8cbc23f05aL68-R68)
[[2]](diffhunk://#diff-8f9b05b82c5484251ba864fad6bd6ec711ff8b9d4ef23929c7122f8cbc23f05aL81-R81)
# Motivation

We expect developers to have `LogInformation` statements (and hence
greater log levels) enabled in production. And so it should provide just
enough information to be achieve the following goals:
- Be able to identify the issues by tracing logs through internal
activity processing pipeline.
- Get suggestions when incomming activity is not handled.
- Have access to metadata that helps us, as SDK owners, with debugging.
- No PIIs should be logged.
- Logs shouldn't be too verbose or contain redundant information.

# Changes
- Removed `BeginScope` since it will add the passed context to every log
statement, forcing the developer to manually configure filtering in
their logging infrastructure.
- On `BotApplication.ProcessAsync` add logging of the MSCV & ServiceUrl.

# How logs look like right now

<img width="1399" height="223"
alt="ae4f3ffc-02ef-40d0-ae81-89848948cde1"
src="https://github.com/user-attachments/assets/e04fe979-83f0-45de-8837-435d809e0a50"
/>

# Program flow and where info logs are present

```mermaid
flowchart TD
      A["Teams Service (POST /api/messages)"]
      B["JWT token validation <br/>ℹ️ token validated successfully "]
      C["BotApplication.ProcessAsync<br/>ℹ️ Activity received <br/>ℹ️ Finished processing activity"]
      D["TurnMiddleware Pipeline"]
      E["TeamsBotApplication.OnActivity<br/>ℹ️ Routing incoming activity"]
      F["Router <br/> ⚠️ no routes found, or registered"]
      G["User Handler"]
      H["ConversationClient  <br/>ℹ️ sending message to url" ]
      I["BotAuthenticationHandler <br/>ℹ️ Acquiring token for scope"]
      J["APX <br/>"]

      A --> B --> C --> D --> E --> F --> G --> H --> I --> J
```
activity.Type,
activity.Id,
activity.ServiceUrl,
httpContext.Request.GetCorrelationVector());

Check failure

Code scanning / CodeQL

Log entries created from user input High

This log entry depends on a
user-provided value
.

Copilot Autofix

AI 10 days ago

In general, to fix log forging issues you ensure any user-controlled values going into logs are normalized so they cannot inject extra log entries or otherwise confuse log parsers. For plain-text logs this typically means removing or replacing newline (\r, \n) and other control characters from user input before logging.

For this codebase, the best focused change is to sanitize the correlation vector value returned by HttpRequestExtensions.GetCorrelationVector so that any consumer (including the logging in BotApplication.ProcessAsync) receives a cleaned value. We do this centrally in the extension method, rather than modifying all call sites. A minimal, non-breaking sanitization is to strip \r and \n characters (and optionally trim surrounding whitespace) from the header value; this preserves the content for correlation purposes while preventing log forging in plain-text outputs.

Concretely:

  • In core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs, change GetCorrelationVector from a single expression-bodied member to a block that:
    • Returns string.Empty if request is null.
    • Retrieves the first header value as before.
    • If it is null, returns string.Empty.
    • Otherwise removes \r and \n characters (using Replace) and optionally Trim()s the result.
  • No changes are required in BotApplication.cs because it will automatically get the sanitized value when calling GetCorrelationVector.

No new external dependencies are needed; we only use string.Replace and Trim, which are part of System.String.

Suggested changeset 1
core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs b/core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs
--- a/core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs
+++ b/core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs
@@ -12,7 +12,22 @@
 {
     /// <summary>
     /// Gets the Microsoft Correlation Vector (MS-CV) from the request headers, if present.
+    /// The value is sanitized to remove any newline characters to prevent log forging.
     /// </summary>
     public static string? GetCorrelationVector(this HttpRequest request)
-        => request != null ? request.Headers["MS-CV"].FirstOrDefault() : string.Empty;
+    {
+        if (request == null)
+        {
+            return string.Empty;
+        }
+
+        var correlationVector = request.Headers["MS-CV"].FirstOrDefault();
+        if (correlationVector == null)
+        {
+            return string.Empty;
+        }
+
+        // Remove carriage return and line feed characters to avoid log forging issues.
+        return correlationVector.Replace("\r", string.Empty).Replace("\n", string.Empty).Trim();
+    }
 }
EOF
@@ -12,7 +12,22 @@
{
/// <summary>
/// Gets the Microsoft Correlation Vector (MS-CV) from the request headers, if present.
/// The value is sanitized to remove any newline characters to prevent log forging.
/// </summary>
public static string? GetCorrelationVector(this HttpRequest request)
=> request != null ? request.Headers["MS-CV"].FirstOrDefault() : string.Empty;
{
if (request == null)
{
return string.Empty;
}

var correlationVector = request.Headers["MS-CV"].FirstOrDefault();
if (correlationVector == null)
{
return string.Empty;
}

// Remove carriage return and line feed characters to avoid log forging issues.
return correlationVector.Replace("\r", string.Empty).Replace("\n", string.Empty).Trim();
}
}
Copilot is powered by AI and may make mistakes. Always verify output.

// TODO: Replace with structured scope data, ensure it works with OpenTelemetry and other logging providers
using (_logger.BeginScope("ActivityType={ActivityType} ActivityId={ActivityId} ServiceUrl={ServiceUrl} MSCV={MSCV}",
activity.Type, activity.Id, activity.ServiceUrl, httpContext.Request.GetCorrelationVector()))

Check failure

Code scanning / CodeQL

Log entries created from user input High

This log entry depends on a
user-provided value
.

Copilot Autofix

AI 6 days ago

In general, to fix log-forging issues, any user-controlled value that is written to logs should be sanitized so that it cannot inject additional log entries or otherwise break log formatting. For plain text logs this usually means stripping CR/LF and related control characters; for HTML logs it means HTML-encoding before logging.

Here, the problematic value is the correlation vector obtained via HttpRequestExtensions.GetCorrelationVector(). The best fix with minimal behavior change is to sanitize this value at the point it is read from the headers, so that all usages (current and future) get a safe version. We can update GetCorrelationVector so that it strips carriage returns and newlines from the header value before returning it. This leaves the observable token value almost unchanged for legitimate clients (correlation vectors should not contain these characters anyway) while protecting the logging calls in BotApplication.

Concretely:

  • In core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs, change GetCorrelationVector from a single expression-bodied member that returns request.Headers["MS-CV"].FirstOrDefault() to a small method that:
    • Returns string.Empty if request is null.
    • Reads the header value into a local variable.
    • If null or empty, returns it as-is.
    • Otherwise removes \r and \n characters (and we can safely also strip \u2028 and \u2029 if desired, but at minimum CR/LF) via Replace.
  • No changes are necessary in BotApplication.cs because after this change httpContext.Request.GetCorrelationVector() will already be sanitized when passed into _logger.LogInformation and _logger.BeginScope.

No new imports are required; string.Replace is in System, and we are already in C# with no additional dependencies.

Suggested changeset 1
core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs b/core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs
--- a/core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs
+++ b/core/src/Microsoft.Teams.Bot.Core/HttpRequestExtensions.cs
@@ -12,7 +12,24 @@
 {
     /// <summary>
     /// Gets the Microsoft Correlation Vector (MS-CV) from the request headers, if present.
+    /// The value is sanitized to remove line breaks to prevent log forging.
     /// </summary>
     public static string? GetCorrelationVector(this HttpRequest request)
-        => request != null ? request.Headers["MS-CV"].FirstOrDefault() : string.Empty;
+    {
+        if (request == null)
+        {
+            return string.Empty;
+        }
+
+        var correlationVector = request.Headers["MS-CV"].FirstOrDefault();
+        if (string.IsNullOrEmpty(correlationVector))
+        {
+            return correlationVector;
+        }
+
+        // Remove CR/LF to avoid log forging via header values.
+        return correlationVector
+            .Replace("\r", string.Empty)
+            .Replace("\n", string.Empty);
+    }
 }
EOF
@@ -12,7 +12,24 @@
{
/// <summary>
/// Gets the Microsoft Correlation Vector (MS-CV) from the request headers, if present.
/// The value is sanitized to remove line breaks to prevent log forging.
/// </summary>
public static string? GetCorrelationVector(this HttpRequest request)
=> request != null ? request.Headers["MS-CV"].FirstOrDefault() : string.Empty;
{
if (request == null)
{
return string.Empty;
}

var correlationVector = request.Headers["MS-CV"].FirstOrDefault();
if (string.IsNullOrEmpty(correlationVector))
{
return correlationVector;
}

// Remove CR/LF to avoid log forging via header values.
return correlationVector
.Replace("\r", string.Empty)
.Replace("\n", string.Empty);
}
}
Copilot is powered by AI and may make mistakes. Always verify output.
rido-min and others added 3 commits March 3, 2026 17:09
…lds) (#360)

This pull request introduces comprehensive changes to support
nullability for key properties in activity-related classes and their
usage throughout the codebase. The main goal is to improve robustness
when handling activities that may lack sender, recipient, or
conversation information, and to ensure consistent null handling in both
implementation and tests.

Key changes include:

- Making `From`, `Recipient`, and `Conversation` properties nullable in
activity and related classes.
- Updating constructors, methods, and serialization logic to handle
possible null values.
- Adjusting tests to account for and verify nullability.

The most important changes are:

**Core Schema and Model Updates:**

* Made the `From`, `Recipient`, and `Conversation` properties nullable
in `CoreActivity`, `TeamsActivity`, and related classes, and updated
constructors to handle null inputs gracefully. This ensures activities
can be created and processed even when some participants or conversation
info are missing.
[[1]](diffhunk://#diff-aa65632fe28a87aec3d29025384c7f1e687d5839d848f1220e8ed59e76dcd35bL55-R63)
[[2]](diffhunk://#diff-b9fe8c2661f373312865c34021dcd68b97c7a7308d3814767e941a9e275212f4L100-R134)
[[3]](diffhunk://#diff-ab03c7985a1673a73536a9756293c78cba898a0de6197501e596ad144582a41aL31-R36)
[[4]](diffhunk://#diff-5b4ce81153a4e786cdcc3ed1fce3951c3285b532d484ec1df6b20d9e40a359e4L48-R54)
* Changed entity and attachment collections (`EntityList`,
`TeamsAttachment`) to return `null` instead of empty collections when
input JSON arrays are null, standardizing the nullability contract.
[[1]](diffhunk://#diff-54676e96eda404a3efa65124857df40e5cb3e19ec4a2b1222c9e08cacac8eaa0L46-R50)
[[2]](diffhunk://#diff-7d6dee59c1c828283d2d29d6f55c39949d8a35887c613f85643286c553e6f1a3L118-R122)

**Method and API Usage Adjustments:**

* Updated various method signatures and internal usages to accept
nullable types and to check for nulls before accessing properties,
including in `WithFrom`, `WithRecipient`, and `WithConversation` builder
methods, and in `AgenticIdentity` extraction logic.
[[1]](diffhunk://#diff-5e00975e375bcb87e6b0d28d2367d865865a1254f089cfcab0d6abbb5db4be38L147-R152)
[[2]](diffhunk://#diff-21605a1ddfd84b8b511a41a957d5e130441cf05eb3dc192579480425e0746a0aL58-R58)
[[3]](diffhunk://#diff-2b447b715e5c577302421ca232985ced9354b64def7b26219525758928d097daL61-R61)
[[4]](diffhunk://#diff-d62a8ce4aac677906758eb430b84c9432f61ff95342701fdcae909310e2aed27L69-R69)
[[5]](diffhunk://#diff-d62a8ce4aac677906758eb430b84c9432f61ff95342701fdcae909310e2aed27L99-R99)
[[6]](diffhunk://#diff-d62a8ce4aac677906758eb430b84c9432f61ff95342701fdcae909310e2aed27L153-R153)
[[7]](diffhunk://#diff-b9be640e365d9187b0d1a2021dddb84311b737f8c28b16428e3b2a450a4f331aL152-R152)

**Test Suite Updates:**

* Updated unit tests to expect nulls for properties and collections
where appropriate, and to use null-safe assertions and property access
throughout.
[[1]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL23-R25)
[[2]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL115-R116)
[[3]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL132-R133)
[[4]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL152-R154)
[[5]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL171-R172)
[[6]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL262-R262)
[[7]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL292-R292)
[[8]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL415-R415)
[[9]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL450-R454)
[[10]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL536-R536)
[[11]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL551-R551)
[[12]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL679-R680)
[[13]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL697-R698)
[[14]](diffhunk://#diff-ec253b7d2876187c3585381aa6cd8b1cbfca2227eb6ac23752253bbcda19484fL714-R714)

**Constructor and Null Handling Improvements:**

* Constructors for `TeamsConversationAccount` and `TeamsConversation`
now handle null arguments without throwing exceptions, returning early
if input is null.
[[1]](diffhunk://#diff-ab03c7985a1673a73536a9756293c78cba898a0de6197501e596ad144582a41aL31-R36)
[[2]](diffhunk://#diff-5b4ce81153a4e786cdcc3ed1fce3951c3285b532d484ec1df6b20d9e40a359e4L48-R54)

**General Codebase Consistency:**

* Ensured all usages of `From`, `Recipient`, `Conversation`, `Entities`,
and `Attachments` are null-safe across the codebase, including in
activity updates, deletions, and proactive messaging scenarios.
[[1]](diffhunk://#diff-b9be640e365d9187b0d1a2021dddb84311b737f8c28b16428e3b2a450a4f331aL152-R152)
[[2]](diffhunk://#diff-b9fe8c2661f373312865c34021dcd68b97c7a7308d3814767e941a9e275212f4R74-R88)

These changes collectively make the bot framework more resilient to
incomplete or partially populated activities and improve code safety and
clarity when handling optional data.
- Removed TeamsBotApplicationBuilder and static CreateBuilder/Run
pattern.
- Introduced DI-based AddTeamsBotApplication<TApp>() and
UseTeamsBotApplication<TApp>() extension methods for flexible bot
registration and endpoint configuration.
- Added CustomHosting sample project demonstrating custom
TeamsBotApplication subclassing and registration.
- Renamed ITurnMiddleWare to ITurnMiddleware; updated middleware usage
to UseMiddleware.
- Made ConversationClient and UserTokenClient methods virtual for
extensibility.
- Improved type safety, replaced var with explicit types, and modernized
code style across samples and tests.
- Updated all samples to use new hosting and middleware APIs.
- Improved documentation, error handling, and code consistency.
- No breaking changes for DI-based consumers; legacy builder pattern
removed.

This pull request introduces a new `CustomHosting` sample to demonstrate
custom hosting scenarios for Teams bots, and applies a variety of
improvements and modernizations across several existing bot samples. Key
changes include the addition of the `CustomHosting` project, improved
type safety, modernization of code patterns, and minor cleanup of unused
usings and dependencies.

**New Sample: Custom Hosting**

* Added a new sample project `CustomHosting`, including
`CustomHosting.csproj`, `MyTeamsBotApp.cs`, `Program.cs`, and
`appsettings.json`, to demonstrate how to set up and run a Teams bot
application with custom hosting logic. (`core/core.slnx`,
`core/samples/CustomHosting/CustomHosting.csproj`,
`core/samples/CustomHosting/MyTeamsBotApp.cs`,
`core/samples/CustomHosting/Program.cs`,
`core/samples/CustomHosting/appsettings.json`)
[[1]](diffhunk://#diff-19ad97af5c1b7109a9c62f830310091f393489def210b9ec1ffce152b8bf958cR18)
[[2]](diffhunk://#diff-9a0a358fefed3a2d514a075dde6393f9d54f88b65e6701443355af6741f8ce80R1-R13)
[[3]](diffhunk://#diff-ec0a36e06aeb2c4f3f7620e01891a6123198cfac9bf6bf1e851ccd913e5b8440R1-R20)
[[4]](diffhunk://#diff-71299e3fd10a90f2601fa1e84cdda5006a3cf3676a2fb32e2ef1e830608558f2R1-R15)
[[5]](diffhunk://#diff-1741a37e03d344704fdb47a90f621df777f6d1888075ec76923bb392ac4e5d0cR1-R9)

**Type Safety and Modernization**

* Improved type safety and code clarity in multiple samples by using
explicit types (e.g., `ChatMessage?`, `SendActivityResponse?`,
`JObject?`, `IList<MeetingParticipantMember>`, etc.), nullable reference
types, and modern C# object initializers.
(`core/samples/AFBot/Program.cs`, `core/samples/CompatBot/EchoBot.cs`,
`core/samples/MeetingsBot/Program.cs`,
`core/samples/AllInvokesBot/Program.cs`,
`core/samples/MessageExtensionBot/Program.cs`)
[[1]](diffhunk://#diff-b2eaa16ee58a54a25acb5e930ace0fe03ca3dea7b34c67a265dcddc8500ae41bL48-R57)
[[2]](diffhunk://#diff-b9be640e365d9187b0d1a2021dddb84311b737f8c28b16428e3b2a450a4f331aL50-R54)
[[3]](diffhunk://#diff-b9be640e365d9187b0d1a2021dddb84311b737f8c28b16428e3b2a450a4f331aL81-R96)
[[4]](diffhunk://#diff-b9be640e365d9187b0d1a2021dddb84311b737f8c28b16428e3b2a450a4f331aL126-R132)
[[5]](diffhunk://#diff-b0cc7807e2f91f921ec82978833465533c565f637b0aa56802f0d713f6688306L15-R38)
[[6]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L31-R47)
[[7]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L51-R58)
[[8]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L91-R99)
[[9]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L113-R130)
[[10]](diffhunk://#diff-9da189387a8b06507339b8044bf5a572c0f84620969ebe735248a73252da901fL33-R33)

* Updated middleware usage patterns and naming to align with modern
conventions (e.g., using `UseMiddleware` instead of `Use`, fixing
interface name typo from `ITurnMiddleWare` to `ITurnMiddleware`).
(`core/samples/AFBot/DropTypingMiddleware.cs`,
`core/samples/AFBot/Program.cs`)
[[1]](diffhunk://#diff-b921767a8b614972c7a3bb5308b4fd797c60d44de331b9656065f3adbee7a248L9-R9)
[[2]](diffhunk://#diff-b2eaa16ee58a54a25acb5e930ace0fe03ca3dea7b34c67a265dcddc8500ae41bL31-R32)

**Dependency and Usings Cleanup**

* Removed unused or redundant `using` statements from several files for
clarity and maintainability.
(`core/samples/CompatProactive/ProactiveWorker.cs`,
`core/samples/CompatBot/Cards.cs`, `core/samples/CoreBot/Program.cs`,
`core/samples/AllInvokesBot/Cards.cs`)
[[1]](diffhunk://#diff-cb27bc8500d98e9cd996a878c9d25274502563720748d6ba31525b75e46bbc46L4-L8)
[[2]](diffhunk://#diff-cef44960d160cf6ea51b595745c079353501a962650d7c9684bd9fa6e1456220L4-L6)
[[3]](diffhunk://#diff-b94b53965e9052345453f2ab6bec21420a36c4b67c9a6c568b9c80edcd0882d1L4)
[[4]](diffhunk://#diff-935a6ffb850a503e4af48c17543f2215a7ab022dd4835efb60f8207c01698520L5)

**Project and Build System Updates**

* Added the new `CustomHosting` sample to the solution file `core.slnx`
for inclusion in the build.

**Minor Fixes and Consistency Improvements**

* Standardized variable naming and initialization, improved null
handling, and modernized HTTP client usage in the AllInvokesBot and
other samples. (`core/samples/AllInvokesBot/Program.cs`)
[[1]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L31-R47)
[[2]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L51-R58)
[[3]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L91-R99)
[[4]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L113-R130)
[[5]](diffhunk://#diff-8f290ac497e620d9799b6a57476f6d5051a39df15e2bb71755ffb6849d2b1b35L283-R288)

These changes collectively improve the maintainability, clarity, and
extensibility of the sample bots, while providing a new example for
custom hosting scenarios.
Port `CitationEntity` and supporting types from main, adapted for
`next/core`.

- Adds `AddCitation`, `AddAIGenerated`, and `AddFeedback` methods to
`TeamsActivity`
- Enables `OMessage` sub-dispatch in `EntityList.FromJsonArray()` with
`@type` routing (`"Message"` --> `CitationEntity`, `"CreativeWork"` -->
`SensitiveUsageEntity`)
- Adds typed `FeedbackLoopEnabled` property to `TeamsChannelData`
- Registers new citation types in `TeamsActivityJsonContext`:
(`CitationEntity`, `CitationClaim`, `CitationAppearanceDocument`,
`CitationImageObject`, `CitationAppearance`)
- Registers previously missing entity types in
`TeamsActivityJsonContext`: (`OMessageEntity`, `SensitiveUsageEntity`,
`DefinedTerm`, `ProductInfoEntity`, `StreamInfoEntity`)
- Unit tests

### Notes
- Not porting `UpdateEntity(IEntity, IEntity`); `AddCitation` does
remove + add inline
- `Samples.AI/CitationsHandler` not ported
- `IMessageEntity` not needed - concrete classes only in 2.1
- `IMessageJsonConverter` replaced by `DeserializeMessageEntity` in
EntityList

---------

Co-authored-by: Corina Gum <>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants