Skip to content

Detach OAuth continuation replay from token-exchange invoke#464

Open
Carvalh0XYZ wants to merge 1 commit into
microsoft:mainfrom
Carvalh0XYZ:fix/detach-token-exchange-replay
Open

Detach OAuth continuation replay from token-exchange invoke#464
Carvalh0XYZ wants to merge 1 commit into
microsoft:mainfrom
Carvalh0XYZ:fix/detach-token-exchange-replay

Conversation

@Carvalh0XYZ

Copy link
Copy Markdown
Contributor

Fixes #463.

Description

This detaches the original-message replay from the signin/tokenExchange request lifecycle.

After a successful auth intercept, the SDK now:

  • saves the completed auth state before returning;
  • deep-copies the continuation activity and reapplies the current conversation reference;
  • starts a separate proactive turn through continue_conversation_with_claims();
  • keeps a strong reference to the background task and logs replay failures;
  • leaves the original invoke TurnContext untouched.

The replay still enters the normal _on_turn pipeline as the original message activity, with its original channel and claims identity.

This mirrors the lifecycle fix made for the JavaScript SDK in microsoft/Agents-for-js#1013.

Testing

  • Added a regression test that blocks the replay and proves the token-exchange turn returns first.
  • The test also verifies auth state is saved, the original invoke context is unchanged, and the replay preserves the composite msteams:COPILOT channel.
  • Hosting-core suite: 2,252 passed, 6 skipped.
  • Black check passed for the changed library file.

Live validation

Validated with a deployed Microsoft 365 Copilot custom-engine agent after clearing both Bot Framework token partitions:

  • token-exchange handling began at 21:06:55.793;
  • auth state was saved at 21:06:56.286;
  • the invoke returned HTTP 200 at 21:06:56.294;
  • the replay began afterward at 21:06:56.299;
  • the final streamed message was sent at 21:07:01.361.

The user received one answer with silent SSO, no sign-in card, and no retry loop.

Copilot AI review requested due to automatic review settings July 10, 2026 21:12
@Carvalh0XYZ Carvalh0XYZ requested a review from a team as a code owner July 10, 2026 21:12

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

Detaches OAuth continuation replay from the signin/tokenExchange invoke lifecycle so the invoke response can return promptly while the original message is replayed asynchronously via a proactive turn.

Changes:

  • Starts OAuth continuation replay in a background task using continue_conversation_with_claims() and tracks tasks to prevent premature GC.
  • Deep-copies the continuation activity and reapplies the current conversation reference before replaying.
  • Adds a regression test ensuring the invoke completes before the replay finishes and that state is saved.

Reviewed changes

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

File Description
tests/hosting_core/app/test_agent_application.py Adds regression coverage verifying token-exchange invoke returns before continuation replay completes.
libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/agent_application.py Moves continuation replay off the invoke call path into a background proactive continuation task.

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

Copilot AI review requested due to automatic review settings July 10, 2026 21:20
@Carvalh0XYZ Carvalh0XYZ force-pushed the fix/detach-token-exchange-replay branch from 60b33aa to 50cd3fa Compare July 10, 2026 21:20

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.

Copilot AI review requested due to automatic review settings July 10, 2026 21:33
@Carvalh0XYZ Carvalh0XYZ force-pushed the fix/detach-token-exchange-replay branch from 50cd3fa to fb89185 Compare July 10, 2026 21:33
@Carvalh0XYZ

Copy link
Copy Markdown
Contributor Author

One extra compatibility detail came out while checking this feedback: the old shallow-copied context also shared the completed OAuth token cache with the replayed message. A fresh proactive context does not.

The latest commit now copies only those completed OAuth token entries into the replay context before running the message. It deliberately does not copy the whole invoke turn_state or its connector clients. The lifecycle test now verifies the replay can read the cached token, keeps the original message ID, uses the current invoke addressing, and starts only after state is saved.

Focused authorization/application tests: 79 passed.

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 3 out of 3 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] OAuth continuation replay keeps signin/tokenExchange invoke open

3 participants