Skip to content

fix(dotnet): recover from dropped session idle events - #2016

Open
hydraxman wants to merge 5 commits into
github:mainfrom
hydraxman:fix/dotnet-session-idle-reliability
Open

fix(dotnet): recover from dropped session idle events#2016
hydraxman wants to merge 5 commits into
github:mainfrom
hydraxman:fix/dotnet-session-idle-reliability

Conversation

@hydraxman

@hydraxman hydraxman commented Jul 17, 2026

Copy link
Copy Markdown

Summary

  • make .NET SendAndWaitAsync recover when the ephemeral session.idle notification is dropped
  • use the runtime's task-drain and activity RPCs as the authoritative fallback
  • flush the SDK's FIFO event-dispatch queue and reject stale inactive snapshots when new events or work appear during confirmation
  • preserve the existing event-only completion path for older runtimes that do not expose the fallback RPCs

Reproduction

  • Before: the dropped-idle transport reproducer times out after receiving the assistant response and assistant.turn_end
  • After: the same public SDK call completes after the runtime reports no active work and preceding user handlers have drained
  • A second transport reproducer reactivates runtime work during the final dispatch barrier and verifies the stale inactive snapshot is not used
  • A legacy-runtime reproducer returns JSON-RPC method-not-found for the fallback API and verifies a later session.idle still completes the call

Tests

  • $HOME/.dotnet/dotnet test test/GitHub.Copilot.SDK.Test.csproj -f net8.0 --no-restore --filter 'FullyQualifiedName~SendAndWaitAsync_Completes_When_SessionIdle_Notification_Is_Dropped|FullyQualifiedName~SendAndWaitAsync_Preserves_Event_Completion_When_Legacy_Runtime_Lacks_Fallback_Rpcs|FullyQualifiedName~SendAndWaitAsync_DroppedIdle_Fallback_Flushes_Preceding_Event_Handlers|FullyQualifiedName~SendAndWaitAsync_DroppedIdle_Fallback_Rechecks_Activity_After_Final_Barrier' — 4 passed
  • $HOME/.dotnet/dotnet test test/GitHub.Copilot.SDK.Test.csproj -f net8.0 --no-restore — 690 passed, 3 skipped
  • $HOME/.dotnet/dotnet build src/GitHub.Copilot.SDK.csproj --no-restore — 0 warnings, 0 errors
  • $HOME/.dotnet/dotnet format --verify-no-changes --no-restore
  • git diff --check

Fixes #2008

@hydraxman
hydraxman force-pushed the fix/dotnet-session-idle-reliability branch from 11e23c4 to 57c96dd Compare July 17, 2026 02:27
Copilot AI review requested due to automatic review settings July 22, 2026 14:22
@hydraxman
hydraxman marked this pull request as ready for review July 22, 2026 14:23
@hydraxman
hydraxman requested a review from a team as a code owner July 22, 2026 14:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a resilient .NET SendAndWaitAsync fallback when ephemeral idle notifications are dropped.

Changes:

  • Uses runtime task-drain and activity RPCs to confirm completion.
  • Adds FIFO event-dispatch barriers and stale-activity protection.
  • Adds unit and E2E regression coverage.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
dotnet/src/Session.cs Implements runtime completion fallback and dispatch barriers.
dotnet/test/Unit/ClientSessionLifetimeTests.cs Tests dropped-idle recovery and activity races.
dotnet/test/E2E/SendAndWaitReliabilityE2ETests.cs Adds end-to-end reliability coverage.
test/snapshots/send_and_wait_reliability/should_complete_when_live_sessionidle_is_dropped.yaml Provides the replay fixture.

Comment thread dotnet/src/Session.cs
Comment thread dotnet/test/E2E/SendAndWaitReliabilityE2ETests.cs Outdated
Copilot AI review requested due to automatic review settings July 22, 2026 23:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread dotnet/src/Session.cs Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 23:10
@hydraxman
hydraxman force-pushed the fix/dotnet-session-idle-reliability branch from eb53c32 to de29350 Compare July 23, 2026 23:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread dotnet/src/Session.cs Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 01:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

Comment thread dotnet/src/Session.cs Outdated
Comment thread dotnet/test/Unit/ClientSessionLifetimeTests.cs Outdated
Comment thread dotnet/test/Unit/ClientSessionLifetimeTests.cs Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 23:06
@hydraxman
hydraxman force-pushed the fix/dotnet-session-idle-reliability branch from 47f3640 to 998f42d Compare July 24, 2026 23:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@SteveSandersonMS

Copy link
Copy Markdown
Contributor

Thanks for the careful work here, particularly around FIFO handler completion and the activity races.

Before taking this fix, we need to establish that it matches a real failure mode. The current tests deliberately omit session.idle, but we do not yet have a real-runtime reproduction showing that a live session.idle notification can disappear while the connection remains healthy. Issue #2008 may instead involve resumed-session initialization, subscription timing, or application-level state tracking.

This PR specifically changes SendAndWaitAsync after a new turn has emitted an assistant message or assistant.turn_end. It would not address a consumer waiting for a historical idle event after resume or tracking running state through its own event subscription. Without knowing which flow is failing, the fix is too narrow to associate confidently with #2008 and risks masking the underlying problem.

A small real-runtime reproduction where:

  1. the handler receives the events preceding session.idle,
  2. session.idle is not received, and
  3. the same connection remains operational,

would be extremely useful. It does not need to reproduce Visual Studio itself—a minimal .NET console application would be ideal. With that evidence, we could evaluate this fallback against the actual failure and determine whether it belongs in .NET, the runtime, or all SDKs.

For now, I think we should hold this PR rather than merge a substantial recovery mechanism for a simulated-but-unconfirmed failure mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET: runtime logs forwarding session.idle, but SDK callback never delivers it

3 participants