Skip to content

[CUA] Expose W365 tools to the model and harden session-expiry recovery#325

Merged
desmarest merged 4 commits into
mainfrom
feature/w365-tool-exposure-and-session-recovery
Jun 20, 2026
Merged

[CUA] Expose W365 tools to the model and harden session-expiry recovery#325
desmarest merged 4 commits into
mainfrom
feature/w365-tool-exposure-and-session-recovery

Conversation

@desmarest

@desmarest desmarest commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What

  1. Default W365 tool exposure. Non-duplicate W365 MCP tools are exposed to the model as function tools. IsExcludedFromModelExposure filters out the session-lifecycle wrappers and the W365 tools that duplicate native CUA actions (click/type_text/press_keys/scroll/move_mouse/drag_mouse/get_cursor_position/get_screen_size). Exposed names are tracked so the loop routes those function_calls through the W365 path via InvokeExposedW365ToolAsync (errors returned as text, never aborting the turn). A ToolSteeringAddendum is appended to the system prompt only when tools are actually exposed, so the non-CUA fast path is never told about tools it doesn't have.

  2. Conversation sanitization. SanitizeConversationHistory runs before every model call, dropping unpaired function/computer calls, orphan outputs, and dangling reasoning items that would otherwise make the request invalid.

  3. Session-expiry recovery. RecoverAndStartFreshSessionAsync releases a stale session and starts a fresh one on the existing MCP client. Both the initial and post-action screenshots run through CaptureScreenshotWithRecoveryAsync, and the computer-call recovery sites route through a shared retry helper.

  4. Active-session reset. ConversationSession.ClearActiveSession clears a leftover tracked session id during recovery so StartW365SessionAsync actually starts a new session instead of short-circuiting on a stale id.

Expose non-duplicate W365 MCP tools to the model as function tools, sanitize
conversation history before each model call, and recover from expired sessions
on the screenshot and exposed-tool paths by starting a fresh session.
Copilot AI review requested due to automatic review settings June 18, 2026 23:50
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@desmarest desmarest changed the title Expose W365 tools to the model and harden session-expiry recovery [CUA] Expose W365 tools to the model and harden session-expiry recovery Jun 18, 2026
Comment thread dotnet/w365-computer-use/sample-agent/ComputerUse/ComputerUseOrchestrator.cs Dismissed

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

This PR updates the Windows 365 Computer Use sample orchestrator to (1) expose eligible W365 MCP tools to the model as function tools, and (2) improve resiliency by sanitizing conversation history and hardening recovery from expired/lost W365 sessions.

Changes:

  • Exposes non-excluded W365 MCP tools as function tools (while tracking exposed names and appending tool-steering instructions only when applicable).
  • Adds conversation-history sanitization to prevent invalid next-turn requests (unpaired calls/outputs, dangling reasoning).
  • Refactors session-expiry recovery into shared helpers, including a “start fresh session” path and screenshot retry with recovery.

Comment thread dotnet/w365-computer-use/sample-agent/ComputerUse/ComputerUseOrchestrator.cs Outdated
Comment thread dotnet/w365-computer-use/sample-agent/ComputerUse/ComputerUseOrchestrator.cs Outdated
…oning sanitization

Parse non-string function_call arguments via GetRawText instead of throwing,
and only emit buffered reasoning before its paired tool call so it can't dangle.
denzelpfeifer
denzelpfeifer previously approved these changes Jun 19, 2026
Concurrent RunAsync turns for the same conversation could each take the
reuse "initial screenshot" branch and append an input_image to the shared
ConversationHistory, producing the Azure OpenAI 400 "Computer tool cannot
use multiple image inputs."

Add a per-conversation SemaphoreSlim (TurnLock) on ConversationSession and
split RunAsync into a thin locking wrapper around a RunTurnAsync core so
turns for the same conversation run one at a time.
These W365 tools were grouped with the native-CUA duplicates and excluded
from model exposure, but the native computer tool cannot emit them — they
are query-only and have no native equivalent, so excluding them removed the
capability entirely. Drop them from the native-duplicate set.
@desmarest desmarest enabled auto-merge (squash) June 19, 2026 23:57
@desmarest desmarest merged commit df1ddce into main Jun 20, 2026
34 checks passed
@desmarest desmarest deleted the feature/w365-tool-exposure-and-session-recovery branch June 20, 2026 00:03
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.

6 participants