Skip to content

Implement ClientIO interaction support on Agent-Server#2178

Merged
GeorgeNgMsft merged 14 commits intomainfrom
dev/georgeng/async-clientio-callbacks
Apr 10, 2026
Merged

Implement ClientIO interaction support on Agent-Server#2178
GeorgeNgMsft merged 14 commits intomainfrom
dev/georgeng/async-clientio-callbacks

Conversation

@GeorgeNgMsft
Copy link
Copy Markdown
Contributor

@GeorgeNgMsft GeorgeNgMsft commented Apr 9, 2026

Async ClientIO Callbacks: Non-Blocking Deferred-Promise Pattern
Three ClientIO methods — askYesNo, proposeAction, and popupQuestion — were previously implemented as blocking RPC invoke calls in the agent server. This meant the server-side command processing was tied to a specific client connection: a disconnect would permanently hang the operation, reconnecting clients couldn't recover pending questions, and popupQuestion was entirely disabled in server mode.

This PR converts all three to a non-blocking deferred-promise pattern:

The server generates a unique interactionId, logs the pending interaction to the DisplayLog, stores a deferred Promise in a new PendingInteractionManager, and sends a fire-and-forget requestInteraction notification to the client(s). Command processing suspends at await as before, but is no longer coupled to the connection.

The client responds via a new respondToInteraction dispatcher method, which resolves the deferred promise and resumes processing exactly where it left off.
On client disconnect, pending interactions owned by that connection are cancelled (rejecting their promises), and all callers treat this as a cancellation of the operation.
popupQuestion is now fully supported in server mode via broadcast to all connected clients, with first-responder resolution.

Pending interactions are logged to DisplayLog so they can be replayed to reconnecting or newly joining clients.
Existing callers (askYesNoWithContext, confirmTranslation, sessionContext.popupQuestion) required no changes — the ClientIO interface signatures are unchanged.

GeorgeNgMsft and others added 3 commits April 8, 2026 13:33
Proposes converting the blocking askYesNo, proposeAction, and
popupQuestion callbacks to a non-blocking deferred-promise pattern
modeled on the existing requestChoice/respondToChoice mechanism.
Covers protocol changes, DisplayLog schema extensions, pending
interaction management, replay/reconnection strategy, and a
phased implementation plan.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cks (Phases 1-8)

Convert askYesNo, proposeAction, and popupQuestion from blocking RPC
callbacks to a non-blocking deferred-promise pattern with correlation
IDs, enabling multi-client broadcast and resilient disconnect handling.

- Define PendingInteractionRequest/Response types and discriminated
  union for askYesNo, proposeAction, popupQuestion interaction types
- Add PendingInteractionManager with create/resolve/cancel lifecycle,
  per-connection cleanup, and timeout support
- Extend DisplayLog with logPendingInteraction and logInteractionResolved
  for interaction persistence and replay
- Add requestInteraction/interactionResolved fire-and-forget methods to
  ClientIO interface and wire through RPC client/server layers
- Add respondToInteraction to Dispatcher interface with RPC support
- Rewrite SharedDispatcher to use deferred promises instead of blocking
  callbacks, with broadcast to all clients and first-responder resolution
- Add requestInteraction/interactionResolved stubs to all ClientIO
  implementations (shell, CLI, browser extension, console, MCP, tests)
- Add @typeagent/dispatcher-types dependency to agent-server and protocol

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@GeorgeNgMsft GeorgeNgMsft changed the title Implement ClientIO interactions on Agent-Server Explore ClientIO interactions on Agent-Server Apr 9, 2026
@GeorgeNgMsft GeorgeNgMsft changed the title Explore ClientIO interactions on Agent-Server Implement ClientIO interaction support on Agent-Server Apr 9, 2026
@GeorgeNgMsft GeorgeNgMsft requested a review from Copilot April 9, 2026 23:38
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 introduces an async “deferred interaction” mechanism for ClientIO prompts in agent-server mode, so server-side command execution is no longer coupled to a single blocking RPC invoke call and can survive disconnect/reconnect scenarios.

Changes:

  • Adds new dispatcher-types for pending interaction requests/responses and extends ClientIO/Dispatcher APIs to support requestInteraction + respondToInteraction.
  • Implements server-side tracking/logging of pending interactions via PendingInteractionManager and new DisplayLog entry types.
  • Wires new RPC surface area and propagates pending interactions to clients on session join.

Reviewed changes

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

Show a summary per file
File Description
ts/pnpm-lock.yaml Adds workspace dependency links for @typeagent/dispatcher-types.
ts/packages/shell/src/renderer/src/main.ts Adds ClientIO stubs for deferred interaction events (currently no-op).
ts/packages/dispatcher/types/src/pendingInteraction.ts New shared types for pending interaction request/response payloads.
ts/packages/dispatcher/types/src/index.ts Re-exports pending interaction types.
ts/packages/dispatcher/types/src/displayLogEntry.ts Adds pending-interaction and interaction-resolved log entry types.
ts/packages/dispatcher/types/src/dispatcher.ts Adds respondToInteraction to the Dispatcher interface.
ts/packages/dispatcher/types/src/clientIO.ts Adds requestInteraction and interactionResolved to ClientIO.
ts/packages/dispatcher/rpc/src/dispatcherTypes.ts Exposes respondToInteraction through dispatcher RPC invoke functions.
ts/packages/dispatcher/rpc/src/dispatcherServer.ts Implements RPC server handler for respondToInteraction.
ts/packages/dispatcher/rpc/src/dispatcherClient.ts Implements RPC client call for respondToInteraction.
ts/packages/dispatcher/rpc/src/clientIOTypes.ts Adds new ClientIO call-function typings for deferred interactions.
ts/packages/dispatcher/rpc/src/clientIOServer.ts Wires new ClientIO call handlers on the RPC server side.
ts/packages/dispatcher/rpc/src/clientIOClient.ts Wires new ClientIO call senders on the RPC client side.
ts/packages/dispatcher/nodeProviders/test/provider.spec.ts Updates test ClientIO stub to satisfy the extended interface.
ts/packages/dispatcher/dispatcher/src/internal.ts Exposes PendingInteractionManager via internal exports.
ts/packages/dispatcher/dispatcher/src/helpers/console.ts Adds no-op stubs for deferred interactions in console ClientIO.
ts/packages/dispatcher/dispatcher/src/displayLog.ts Adds logging helpers for pending interactions and their resolution.
ts/packages/dispatcher/dispatcher/src/dispatcher.ts Adds base respondToInteraction method (throws by default).
ts/packages/dispatcher/dispatcher/src/context/pendingInteractionManager.ts New manager to store deferred promises and handle cancel/resolve.
ts/packages/dispatcher/dispatcher/src/context/interactiveIO.ts Updates nullClientIO to include the new methods.
ts/packages/commandExecutor/src/commandServer.ts Updates MCP ClientIO stub to include the new methods.
ts/packages/cli/src/enhancedConsole.ts Adds no-op stubs for deferred interactions in CLI ClientIO.
ts/packages/agentServer/server/src/sharedDispatcher.ts Implements deferred interaction flow in server shared dispatcher.
ts/packages/agentServer/server/src/sessionManager.ts Returns pending interactions on session join.
ts/packages/agentServer/server/src/server.ts Includes pending interactions in join-session response payload.
ts/packages/agentServer/server/package.json Adds dependency on @typeagent/dispatcher-types.
ts/packages/agentServer/protocol/src/protocol.ts Extends JoinSessionResult with optional pendingInteractions.
ts/packages/agentServer/protocol/package.json Adds dependency on @typeagent/dispatcher-types.
ts/packages/agentServer/docs/async-clientio-design.md Adds design documentation for the deferred interaction pattern.
ts/packages/agents/browser/src/extension/serviceWorker/dispatcherConnection.ts Adds no-op stubs for deferred interactions in extension ClientIO.
Files not reviewed (1)
  • ts/pnpm-lock.yaml: Language not supported

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

@GeorgeNgMsft GeorgeNgMsft marked this pull request as ready for review April 10, 2026 06:59
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 31 out of 32 changed files in this pull request and generated 10 comments.

Files not reviewed (1)
  • ts/pnpm-lock.yaml: Language not supported

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

@GeorgeNgMsft GeorgeNgMsft deployed to development-fork April 10, 2026 08:10 — with GitHub Actions Active
@GeorgeNgMsft GeorgeNgMsft added this pull request to the merge queue Apr 10, 2026
Merged via the queue into main with commit 54f1519 Apr 10, 2026
20 of 21 checks passed
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.

2 participants