Skip to content

Register the agent host protocol channel before starting the local endpoint - #328862

Merged
vijayupadya merged 4 commits into
mainfrom
vijayu/agenthost-ipc-channel-timeout
Aug 5, 2026
Merged

Register the agent host protocol channel before starting the local endpoint#328862
vijayupadya merged 4 commits into
mainfrom
vijayu/agenthost-ipc-channel-timeout

Conversation

@vijayupadya

@vijayupadya vijayupadya commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Problem

On a slow agent host boot, the "agent host Copilot" option was frequently missing from the session-target picker (both the chat editor and the Agents window).

The renderer reaches the agent host over the MessagePort agentHostProtocol IPC channel. The IPC ChannelServer drops calls to a not-yet-registered channel after its unknown-channel timeout (~1s), timed from when it processes the renderer's connect.

That window was being consumed by startLocalAgentHostEndpoint — the external local WebSocket/named-pipe endpoint — sitting on the path before registerChannel. Its ~850ms+ startup pushed registration just over the 1s budget, so the renderer's buffered connect timed out, the connection closed, root state never hydrated, and the option was missing.

Fix

Register the MessagePort Protocol channel as soon as providers are ready — before starting the external endpoint — and start the endpoint afterward with its own ProtocolServerHandler (the same pattern the dynamic/env-var WebSocket servers already use). The endpoint no longer sits on the renderer's connect path.

Timing (time-to-registration)

Before — just over the 1s budget:

+195ms   before local endpoint
+1142ms  local endpoint ready         ← ~850ms endpoint startup ON the path
+1146ms  protocol channel registered  ← >1s → connect times out → connection closed → option missing

After — well inside the budget:

+168ms   providers registered
+170ms   protocol channel registered  ← was +1146ms
+170ms   before local endpoint
+1676ms  local endpoint ready         ← endpoint now OFF the critical path

Result

The agent host option now appears reliably in both the chat editor and the Agents window across cold boots — the channel registers in ~170ms instead of ~1.1s.

Notes

  • The endpoint gets its own handler; verified equivalent to the old CompositeProtocolServer — each handler manages its own clients/broadcasts/replay-buffer/orphan-detection via its own _clients map, and the dynamic/env-var WS handlers already coexist this way.
  • The endpoint handler subscribes to its connections before publishing its discovery metadata, so no client can connect in a gap and be missed.
  • Scope is a single file (agentHostMain.ts). No protocol/wire changes; no change to the WebSocket/remote paths.

Copilot AI review requested due to automatic review settings August 3, 2026 22:08

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 bounded retry handling for transient agent-host IPC channel registration timeouts.

Changes:

  • Adds cancellable exponential-backoff connection retries.
  • Adds tests for success, failure, exhaustion, disposal, and listener counts.
Show a summary per file
File Description
agentHostIpcChannelTransport.ts Implements retry and cancellation logic.
agentHostIpcChannelTransport.test.ts Tests retry behavior and teardown.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/vs/platform/agentHost/browser/agentHostIpcChannelTransport.ts Outdated
@vijayupadya
vijayupadya requested a review from connor4312 August 3, 2026 22:29
@vijayupadya
vijayupadya marked this pull request as ready for review August 3, 2026 23:08

@connor4312 connor4312 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this is the right approach. We should instead figure out why the channel is taking so long to get registered, and solve that, which happens here:

server.registerChannel(AgentHostIpcChannels.Protocol, messagePortProtocolServer);

@vijayupadya

vijayupadya commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

I don't think this is the right approach. We should instead figure out why the channel is taking so long to get registered, and solve that, which happens here:

server.registerChannel(AgentHostIpcChannels.Protocol, messagePortProtocolServer);

@connor4312 , Fair feedback, below is the root cause and proposed fix. Let me know your feedback

Root cause + proposed fix

The renderer connects to the agent host over the MessagePort agentHostProtocol channel. The IPC ChannelServer drops calls to a not-yet-registered channel after ~1s, timed from when it processes the renderer's connect. The relevant window is therefore the time from the server starting to registerChannel(Protocol, …).

That window was being blown by startLocalAgentHostEndpoint (the external WebSocket/named-pipe endpoint) sitting on the path before registerChannel.

Proposed Fix: register the MessagePort Protocol channel right after providers are ready (before the endpoint), and start the endpoint afterward with its own ProtocolServerHandler.

Timing (time-to-registration)

Before — just over the 1s budget:

+195ms   before local endpoint
+1142ms  local endpoint ready         ← ~850ms endpoint startup ON the path
+1146ms  protocol channel registered  ← >1s → connect times out ~70ms earlier → connection closed → option missing

After — well inside the budget:

+168ms   providers registered
+170ms   protocol channel registered  ← was +1146ms
+170ms   before local endpoint
+1676ms  local endpoint ready         ← endpoint now OFF the critical path

Result

The agent host option now appears reliably in the picker (chat editor + Agents window) across cold boots — the channel registers in ~170ms instead of ~1.1s.

Notes

  • Endpoint gets its own handler (same pattern the dynamic/env-var WS servers already use);
  • CompositeProtocolServer — each handler manages its own clients/broadcasts/replay/orphan-detection via its own _clients map.
  • Endpoint handler subscribes to its connections before publishing discovery metadata, so no client can connect in a gap and be missed.
  • Registering the channel first is also more robust: an endpoint failure now degrades to "MessagePort only" instead of tearing down the renderer's channel.

@vijayupadya vijayupadya changed the title Retry the agent host IPC connect on a slow-boot channel-registration timeout Register the agent host protocol channel before starting the local endpoint Aug 4, 2026
@vijayupadya
vijayupadya requested a balanced review from Copilot August 4, 2026 21: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.

Review details

Suppressed comments (5)

src/vs/platform/agentHost/node/agentHostMain.ts:392

  • This multi-line inline comment exceeds the repository's one-line limit for comments inside methods. Keep only the non-obvious ordering constraint.
			// Register the renderer's protocol channel BEFORE starting the external
			// endpoint: the renderer connects over this channel, and the IPC
			// ChannelServer drops calls to a not-yet-registered channel after its
			// unknown-channel timeout (~1s), so the endpoint's socket startup must
			// not sit on this path.

src/vs/platform/agentHost/node/agentHostMain.ts:397

  • This multi-line inline comment exceeds the repository's one-line limit for comments inside methods. Condense it to the ordering decision.
			// The external local endpoint (out-of-process local clients such as the
			// CLI) is not on the renderer's path; start it after registration and
			// give it its own handler.

src/vs/platform/agentHost/node/agentHostMain.ts:408

  • This multi-line inline comment exceeds the repository's one-line limit for comments inside methods. The connection-gap constraint can be stated in one line.
				// Wire the endpoint's handler (subscribing to its connections) BEFORE
				// publishing the metadata that advertises it, so a client can't connect
				// in the gap and be missed.

src/vs/platform/agentHost/node/agentHostMain.ts:425

  • If metadata publication fails, only the WebSocket server is disposed; the ProtocolServerHandler added above remains subscribed to state, MCP, and OTLP events for the process lifetime and keeps filling its replay buffer even though it can no longer serve clients. Dispose the handler with the server by grouping both in an endpoint-local store and adopting that store only after publication succeeds.
					localEndpoint.server.dispose();

src/vs/platform/agentHost/node/agentHostMain.ts:325

  • This multi-line inline comment exceeds the repository's one-line limit for comments inside methods. Condense it so the identifiers carry the remaining explanation.

This issue also appears in the following locations of the same file:

  • line 388
  • line 395
  • line 406
		// Shared config for the local data-plane protocol handlers (renderer
		// MessagePort + the external endpoint, which each get their own handler).
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@vijayupadya
vijayupadya requested a review from connor4312 August 5, 2026 16:05
…channel-timeout

# Conflicts:
#	src/vs/platform/agentHost/node/agentHostMain.ts
@vijayupadya
vijayupadya merged commit 37113d9 into main Aug 5, 2026
63 of 65 checks passed
@vijayupadya
vijayupadya deleted the vijayu/agenthost-ipc-channel-timeout branch August 5, 2026 18:34
@vs-code-engineering vs-code-engineering Bot added this to the 1.133.0 milestone Aug 5, 2026
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.

3 participants