Skip to content

Fix async anti-patterns across all library projects#402

Open
rido-min wants to merge 5 commits intomainfrom
fix/async-issues-396-401
Open

Fix async anti-patterns across all library projects#402
rido-min wants to merge 5 commits intomainfrom
fix/async-issues-396-401

Conversation

@rido-min
Copy link
Copy Markdown
Member

@rido-min rido-min commented Mar 26, 2026

Summary

Fixes #396, #397, #398, #399, #400, #401

Test plan

  • Solution builds with 0 errors
  • All existing tests pass (122 Apps tests, 15 AspNetCore tests, 9 McpClient tests, 3 Graph tests)
  • Verify streaming behavior works correctly with the new EmitAsync method on IStream
  • Verify cancellation propagation works for OpenAI API calls
  • Verify OAuth sign-in flow logs errors appropriately instead of silently swallowing

🤖 Generated with Claude Code

…, fire-and-forget, ConfigureAwait(false)

Comprehensive fix for async anti-patterns across all library projects:

- #396: Replace sync-over-async GetAwaiter().GetResult() with proper await
  in ApplicationBuilder.Functions, Stream, ChatPrompt.Errors, ServiceCollection
- #397: Propagate CancellationToken correctly in OpenAIChatModel.Send,
  Context.Send, HttpClient; add CancellationToken to OnBuildInstructions
- #398: Replace empty catch blocks with exception logging in App.cs,
  Context.SignIn, McpClientPlugin
- #399: Add error handling to fire-and-forget Flush() in AspNetCorePlugin.Stream,
  replace Task.Run(() => {}) with Task.CompletedTask, use _ = discard with
  ConfigureAwait in debounce extensions
- #400: Add ConfigureAwait(false) to ~380 await calls across all library projects
- #401: Replace Task.Run wrapping sync code with direct execution in LocalStorage,
  fix unsafe reflection-based Task.Result access in MethodInfoExtensions

Fixes #396, #397, #398, #399, #400, #401

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 26, 2026 16:11
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 addresses widespread async/await correctness and reliability issues across the Teams SDK libraries by removing sync-over-async patterns, improving cancellation propagation, reducing unobserved task exceptions, and standardizing ConfigureAwait(false) usage in library code.

Changes:

  • Propagates CancellationToken through multiple call chains and updates the IChatPlugin hook signature accordingly.
  • Replaces several fire-and-forget / sync-blocking async patterns with awaited flows and safer wrappers.
  • Adds ConfigureAwait(false) broadly across library awaits to reduce context capture and deadlock risk.

Reviewed changes

Copilot reviewed 114 out of 114 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Tests/Microsoft.Teams.AI.Tests/Utils/TestChatPlugin.cs Update test plugin hook signature
Tests/Microsoft.Teams.AI.Tests/ChatPluginTests.cs Update hook verification for token
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.External/Microsoft.Teams.Plugins.External.McpClient/McpClientPlugin.cs ConfigureAwait + exception logging
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.External/Microsoft.Teams.Plugins.External.Mcp/Extensions/McpServerBuilder.cs ConfigureAwait in prompt send
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/Extensions/ApplicationBuilder.cs ConfigureAwait in endpoint handler
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/Extensions/ApplicationBuilder.Tabs.cs ConfigureAwait on Results execution
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/Extensions/ApplicationBuilder.Functions.cs Remove unobserved handler tasks
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/AspNetCorePlugin.cs ConfigureAwait in send/parse/do
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/AspNetCorePlugin.Stream.cs Add FlushSafe + ConfigureAwait
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.DevTools/WebSocketCollection.cs ConfigureAwait for websocket send
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.DevTools/DevToolsPlugin.cs ConfigureAwait in middleware/events
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.DevTools/Controllers/DevToolsController.cs ConfigureAwait in websocket loop
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.DevTools/Controllers/ActivityController.cs ConfigureAwait in activity creation
Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore.BotBuilder/Controllers/MessageController.cs ConfigureAwait + plugin fallback await
Libraries/Microsoft.Teams.Extensions/Microsoft.Teams.Extensions.Hosting/Microsoft.Teams.Apps.Extensions/TeamsService.cs ConfigureAwait on startup
Libraries/Microsoft.Teams.Extensions/Microsoft.Teams.Extensions.Hosting/Microsoft.Teams.Apps.Extensions/ServiceCollection.cs ConfigureAwait in sync DI factory
Libraries/Microsoft.Teams.Common/Storage/LocalStorage.cs Remove Task.Run for sync ops
Libraries/Microsoft.Teams.Common/Http/HttpClient.cs Propagate cancellation + ConfigureAwait
Libraries/Microsoft.Teams.Common/Extensions/TaskExtensions.cs ConfigureAwait in retry delays
Libraries/Microsoft.Teams.Common/Extensions/MethodInfoExtensions.cs Safer Task result extraction
Libraries/Microsoft.Teams.Common/Extensions/ActionExtensions.cs Debounce: discard + ConfigureAwait
Libraries/Microsoft.Teams.Apps/Routing/Route.cs ConfigureAwait on route invoke
Libraries/Microsoft.Teams.Apps/Events/Topic.cs ConfigureAwait in topic emit
Libraries/Microsoft.Teams.Apps/Events/EventEmitter.cs ConfigureAwait in emitter handlers
Libraries/Microsoft.Teams.Apps/Contexts/Context.cs Replace no-op Task.Run default
Libraries/Microsoft.Teams.Apps/Contexts/Context.SignIn.cs Log instead of empty catch; ConfigureAwait
Libraries/Microsoft.Teams.Apps/Contexts/Context.Send.cs Fix cancellation token propagation
Libraries/Microsoft.Teams.Apps/Contexts/Client/FunctionContext.cs ConfigureAwait in conversation bootstrap
Libraries/Microsoft.Teams.Apps/AppRouting.cs ConfigureAwait across invoke flows
Libraries/Microsoft.Teams.Apps/AppPlugins.cs ConfigureAwait in plugin event broadcast
Libraries/Microsoft.Teams.Apps/AppEvents.cs ConfigureAwait + propagate to plugins
Libraries/Microsoft.Teams.Apps/App.cs ConfigureAwait + log suppressed errors
Libraries/Microsoft.Teams.Apps/Activities/TypingActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Messages/MessageUpdateActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Messages/MessageReactionActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Messages/MessageDeleteActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Messages/MessageActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Tasks/SubmitActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Tasks/FetchActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Tabs/SubmitActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Tabs/FetchActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/SignIn/VerifyStateAcitivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/SignIn/TokenExchangeActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/SignIn/FailureActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Search/TypeaheadSearchActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Search/SearchActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Search/AnswerSearchActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Messages/SubmitActionActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Messages/FeedbackActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/SubmitActionActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/SettingsActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/SelectItemActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/QuerySettingsUrlActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/QueryLinkActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/QueryActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/FetchTaskActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/CardButtonClickedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/MessageExtensions/AnonQueryLinkActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/InvokeActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/HandoffActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/FileConsentActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/ExecuteActionActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Configs/SubmitActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/Configs/FetchActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Invokes/AdaptiveCards/ActionActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Installs/UnInstallActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Installs/InstallUpdateActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Installs/InstallActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Events/ReadReceiptActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Events/MeetingStartActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Events/MeetingLeaveActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Events/MeetingJoinActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Events/MeetingEndActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Events/EventActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/TeamUnArchivedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/TeamRestoredActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/TeamRenamedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/TeamDeletedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/TeamArchivedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/MembersRemovedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/MembersAddedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ConversationUpdateActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ConversationEndActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ChannelUnsharedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ChannelSharedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ChannelRestoredActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ChannelRenamedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ChannelMemberRemovedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ChannelMemberAddedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ChannelDeletedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Conversations/ChannelCreatedActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/CommandResultActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/CommandActivity.cs ConfigureAwait in handler wrappers
Libraries/Microsoft.Teams.Apps/Activities/Activity.cs ConfigureAwait in activity handlers
Libraries/Microsoft.Teams.Apps.Testing/Plugins/TestPlugin.cs ConfigureAwait in test plugin
Libraries/Microsoft.Teams.Api/Clients/UserTokenClient.cs ConfigureAwait in token calls
Libraries/Microsoft.Teams.Api/Clients/TeamClient.cs ConfigureAwait in team calls
Libraries/Microsoft.Teams.Api/Clients/ReactionClient.cs ConfigureAwait in reaction calls
Libraries/Microsoft.Teams.Api/Clients/MemberClient.cs ConfigureAwait in member calls
Libraries/Microsoft.Teams.Api/Clients/MeetingClient.cs ConfigureAwait in meeting calls
Libraries/Microsoft.Teams.Api/Clients/ConversationClient.cs ConfigureAwait in conversation create
Libraries/Microsoft.Teams.Api/Clients/BotTokenClient.cs ConfigureAwait in token resolve
Libraries/Microsoft.Teams.Api/Clients/BotSignInClient.cs ConfigureAwait in sign-in calls
Libraries/Microsoft.Teams.Api/Clients/ActivityClient.cs ConfigureAwait in activity calls
Libraries/Microsoft.Teams.Api/Auth/TokenCredentials.cs ConfigureAwait in token factory
Libraries/Microsoft.Teams.Api/Auth/ClientCredentials.cs ConfigureAwait + cancellation in auth
Libraries/Microsoft.Teams.AI/Stream.cs Add async emission API
Libraries/Microsoft.Teams.AI/Prompts/ChatPrompt/ChatPrompt.Send.cs ConfigureAwait + token propagation
Libraries/Microsoft.Teams.AI/Prompts/ChatPrompt/ChatPrompt.Functions.cs ConfigureAwait in function invoke
Libraries/Microsoft.Teams.AI/Prompts/ChatPrompt/ChatPrompt.Errors.cs Async error handler registration
Libraries/Microsoft.Teams.AI/Prompts/ChatPrompt/ChatPrompt.Chain.cs ConfigureAwait in chained send
Libraries/Microsoft.Teams.AI/ChatPlugin.cs Add CancellationToken to hook
Libraries/Microsoft.Teams.AI/BaseChatPlugin.cs Add CancellationToken to base hook
Libraries/Microsoft.Teams.AI.Models.OpenAI/OpenAIChatModel.Send.cs Propagate token + async streaming

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- FlushSafe: catch specific Exception type with explanatory comment
  about transient flush errors
- McpClientPlugin: pass full Exception object to logger instead of
  just ex.Message, preserving stack traces for diagnostics
- ChatPrompt.Errors: avoid async void event handler by using
  fire-and-forget pattern instead of async lambda
- IStream: use default interface method for EmitAsync to avoid
  breaking external implementers; mark sync Emit as Obsolete
- ActionExtensions: replace ContinueWith(async ...) with proper
  async local function to avoid Task<Task> unwrapping issues

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 114 out of 114 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (2)

Libraries/Microsoft.Teams.AI/Prompts/ChatPrompt/ChatPrompt.Send.cs:65

  • OnChunk swallows all exceptions from the onChunk callback (catch { return; }). Since this is in the send/streaming path, failures become invisible and can leave buffer in a surprising state (it won’t be cleared on exception). At minimum, log or raise ErrorEvent with the exception (and consider whether the buffer should be reset) so callback failures are diagnosable.
            try
            {
                await onChunk(buffer).ConfigureAwait(false);
                buffer = string.Empty;
            }
            catch { return; }
        }

Libraries/Microsoft.Teams.Common/Extensions/ActionExtensions.cs:25

  • Debounce<T> discards the continuation task. If func(arg) throws, the exception is captured on the discarded task and becomes unobserved. Also, the prior CancellationTokenSource is canceled but never disposed, which can leak resources in long-running processes. Wrap func(arg) in a try/catch (or observe/log continuation faults) and ensure old token sources are disposed (e.g., dispose the previous CTS after cancel, or dispose the per-invocation CTS in the continuation).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- FlushSafe: reschedule retry timer on failure to prevent Close()
  from spinning forever when _id is null after a transient send error
- App.cs, Context.SignIn.cs: pass full Exception object to logger
  instead of interpolated ex.Message, preserving stack traces
- ApplicationBuilder.Functions: use FirstOrDefault() instead of
  First() for Authorization header to avoid throwing on missing header
- ChatPrompt.Errors: observe fire-and-forget task faults via
  ContinueWith and log them, instead of silently discarding
- ActionExtensions: catch non-cancellation exceptions in DebounceCore
  to prevent UnobservedTaskException; dispose previous CTS to avoid
  resource leaks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 114 out of 114 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

Libraries/Microsoft.Teams.Common/Extensions/ActionExtensions.cs:25

  • Debounce<T> fires a continuation task and discards it; if func(arg) throws, the continuation will fault and can surface as an unobserved task exception. Wrap func(arg) in try/catch (or refactor to an async core similar to the Func<Task> overload) so exceptions are observed/handled deterministically.
    Libraries/Microsoft.Teams.AI/Prompts/ChatPrompt/ChatPrompt.Send.cs:65
  • OnChunk swallows all exceptions from the user-provided onChunk callback and returns without clearing buffer. If onChunk throws once, buffer will keep growing on subsequent chunks, which can cause unbounded memory growth and makes failures invisible. Consider logging and either clearing the buffer on failure or stopping streaming/propagating the error.
            try
            {
                await onChunk(buffer).ConfigureAwait(false);
                buffer = string.Empty;
            }
            catch { return; }
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@rido-min
Copy link
Copy Markdown
Member Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 26, 2026

@rido-min I've opened a new pull request, #403, to work on those changes. Once the pull request is ready, I'll request review from you.

…ancellationToken propagation in McpClientPlugin (#403)

Three issues flagged in review of the async anti-pattern fixes PR were
left unaddressed.

## Changes

- **`Stream.Emit`** – Remove unnecessary `EmitAsync` indirection; call
`onChunk(text).GetAwaiter().GetResult()` directly.
`ConfigureAwait(false)` on a synchronously-blocked call has no effect.

- **`AspNetCorePlugin.Stream` / `FlushSafe`** – Add optional `ILogger?
Logger` property to the nested `Stream` class. `CreateStream` wires it
to `Logger.Child("stream")`. `FlushSafe` now logs at `Warn` with the
full exception before scheduling the retry timer, making send failures
diagnosable in production.

- **`McpClientPlugin`** – Thread `CancellationToken` from
`OnBuildFunctions` through the full discovery call chain:
  ```
  OnBuildFunctions(cancellationToken)
    → FetchToolsIfNeeded(cancellationToken)
      → FetchToolsFromServer(..., cancellationToken)
→ McpClientFactory.CreateAsync(..., cancellationToken:
cancellationToken)
        → client.ListToolsAsync(cancellationToken: cancellationToken)
  ```
Previously the token was accepted but never forwarded, so callers could
not cancel in-flight tool discovery.

<!-- START COPILOT CODING AGENT TIPS -->
---

⌨️ Start Copilot coding agent tasks without leaving your editor —
available in [VS Code](https://gh.io/cca-vs-code-docs), [Visual
Studio](https://gh.io/cca-visual-studio-docs), [JetBrains
IDEs](https://gh.io/cca-jetbrains-docs) and
[Eclipse](https://gh.io/cca-eclipse-docs).

---------

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
Copy link
Copy Markdown
Member Author

@copilot review the status of the comments on this PR with the latest commits, and resolve comments that are not applicable anymore

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 26, 2026

@copilot review the status of the comments on this PR with the latest commits, and resolve comments that are not applicable anymore

I've reviewed all review comments against the current code (latest commit 9ba530e). Here's the status:

All resolved:

  1. FlushSafe suppresses exceptions (3 rounds of feedback) — Now logs via Logger?.Warn(...) with full exception, plus retry timer for forward progress.
  2. McpClientPlugin catch drops stack trace — Now passes ex object to logger.
  3. ChatPrompt.Errors async void / unobserved task — Uses ContinueWith with OnlyOnFaulted + Logger.Error(t.Exception).
  4. Stream.Emit sync-over-async indirection — Marked [Obsolete], calls onChunk(text).GetAwaiter().GetResult() directly.
  5. ActionExtensions.Debounce Task<Task> / unobserved exceptions — Rewritten with DebounceCore async local function + try/catch, CTS disposed before reuse.
  6. App.cs / Context.SignIn log only ex.Message — Both now pass the exception object to the logger.
  7. ApplicationBuilder.Functions Authorization.First() throws — Changed to FirstOrDefault() is null.
  8. McpClientPlugin ignores CancellationToken — Token threaded through FetchToolsIfNeededFetchToolsFromServer → MCP SDK calls.

Design choice (not a bug):

  1. IStream.EmitAsync breaking changeEmitAsync has a default interface implementation that delegates to Emit(), so existing external implementers won't break. This is an intentional design decision.

MehakBindra
MehakBindra previously approved these changes Mar 31, 2026
Copilot AI review requested due to automatic review settings March 31, 2026 20:41
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 114 out of 114 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@rido-min rido-min linked an issue Mar 31, 2026 that may be closed by this pull request
@rido-min rido-min enabled auto-merge (squash) March 31, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants