Conversation
📬 CODENOTIFYThe following users are being notified based on files changed in this PR: @bpaseroMatched files:
@deepak1556Matched files:
|
There was a problem hiding this comment.
Pull request overview
Reapplies and extends “tunnels work” by wiring Dev Tunnel–backed remote agent host connections into the Sessions app, while also updating the agent-host protocol integration (auth + session flags + terminal schema) across client/server and tests.
Changes:
- Add Dev Tunnel connection support (shared-process tunnel relay + Sessions UI/actions + cached tunnel providers).
- Move auth discovery to
protectedResourceson root agent info and update interactive/eager auth flows accordingly. - Persist and surface session
isRead/isDoneflags (protocol, reducers, side effects, and integration tests), plus sync in updated protocol types.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts | Updates tests to provide shared SessionClientState to handlers. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/loggingAgentConnection.ts | Removes deprecated agent/metadata method proxies; keeps typed protocol calls. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts | Uses shared client state; eager + retry auth based on root protectedResources. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatContribution.ts | Auth flow now derives from root agent protectedResources; forwards all envelopes to shared client state. |
| src/vs/sessions/sessions.desktop.main.ts | Registers tunnel agent host service + contribution in Sessions desktop entrypoint. |
| src/vs/sessions/contrib/remoteAgentHost/electron-browser/tunnelAgentHostServiceImpl.ts | Implements renderer-side tunnel service: token resolution, relay connect, cached tunnels storage. |
| src/vs/sessions/contrib/remoteAgentHost/electron-browser/tunnelAgentHostService.ts | Registers ITunnelAgentHostService singleton. |
| src/vs/sessions/contrib/remoteAgentHost/browser/tunnelAgentHost.contribution.ts | Creates session providers for cached tunnels; silent status checks and on-demand connect. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHostSessionsProvider.ts | Adds connectOnDemand; maps isRead/isDone to UI state; dispatches read/done actions. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHostActions.ts | Adds “Connect via Dev Tunnel” command + tunnel picker/auth flow; updates WebSocket entry shape. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHost.contribution.ts | Adapts to typed remote entry model; auth via protectedResources; adds chat.remoteAgentTunnels setting. |
| src/vs/sessions/contrib/localAgentHost/browser/localAgentHostSessionsProvider.ts | Adds isRead/isDone support and dispatches persistence actions for local agent host sessions. |
| src/vs/sessions/contrib/chat/browser/sessionWorkspacePicker.ts | Adds tunnel UI affordances (“Tunnels…” entry + tunnel-specific selection behavior). |
| src/vs/platform/agentHost/test/node/protocolWebSocket.integrationTest.ts | Adds E2E coverage for persisting isRead/isDone to listSessions. |
| src/vs/platform/agentHost/test/node/protocolServerHandler.test.ts | Updates tests to match typed authenticate request behavior. |
| src/vs/platform/agentHost/test/node/mockAgent.ts | Updates mock agent protected-resources typing and marks Copilot resource as required. |
| src/vs/platform/agentHost/test/node/agentService.test.ts | Removes tests for deleted listAgents/refreshModels/getResourceMetadata APIs. |
| src/vs/platform/agentHost/test/electron-browser/remoteAgentHostService.test.ts | Updates tests for new raw/typed remote entry model and address derivation. |
| src/vs/platform/agentHost/node/tunnelAgentHostService.ts | Adds shared-process tunnel relay main service using dev-tunnels SDK. |
| src/vs/platform/agentHost/node/protocolServerHandler.ts | Adds protocol fields isRead/isDone; adds typed authenticate; adds terminal command stubs. |
| src/vs/platform/agentHost/node/copilot/copilotAgent.ts | Moves Copilot auth requirement to protectedResources with required: true. |
| src/vs/platform/agentHost/node/agentSideEffects.ts | Emits agent protectedResources; persists isRead/isDone session flags via metadata. |
| src/vs/platform/agentHost/node/agentService.ts | Removes deprecated APIs; overlays/persists isRead/isDone from session DB metadata. |
| src/vs/platform/agentHost/electron-browser/tunnelRelayTransport.ts | Adds renderer transport that relays protocol messages through shared process tunnel service. |
| src/vs/platform/agentHost/electron-browser/sshRemoteAgentHostServiceImpl.ts | Updates SSH connection registration to new typed entry shape. |
| src/vs/platform/agentHost/electron-browser/remoteAgentHostServiceImpl.ts | Implements raw↔typed entry conversions; handles WebSocket vs SSH vs Tunnel connection lifecycles. |
| src/vs/platform/agentHost/electron-browser/remoteAgentHostProtocolClient.ts | Switches authenticate to typed protocol request; adds isRead/isDone mapping from listSessions. |
| src/vs/platform/agentHost/electron-browser/agentHostService.ts | Removes deprecated forwarding methods from agent host IPC proxy. |
| src/vs/platform/agentHost/common/tunnelAgentHost.ts | Defines tunnel agent host service contracts, constants, and data types. |
| src/vs/platform/agentHost/common/state/sessionState.ts | Re-exports ITerminalState type. |
| src/vs/platform/agentHost/common/state/sessionClientState.ts | Broadens snapshot typing to include terminal state (needs follow-up handling). |
| src/vs/platform/agentHost/common/state/sessionActions.ts | Re-exports new session action types (isRead/isDone) from protocol. |
| src/vs/platform/agentHost/common/state/protocol/version/registry.ts | Updates action version registry for new session + terminal actions. |
| src/vs/platform/agentHost/common/state/protocol/state.ts | Adds session flags + tool-call partial content + terminal state types. |
| src/vs/platform/agentHost/common/state/protocol/reducers.ts | Adds session/tool/terminal reducer updates and client-dispatchable validation changes. |
| src/vs/platform/agentHost/common/state/protocol/messages.ts | Adds createTerminal/disposeTerminal to typed command map. |
| src/vs/platform/agentHost/common/state/protocol/commands.ts | Adds terminal commands and terminal-claim types in command schema. |
| src/vs/platform/agentHost/common/state/protocol/actions.ts | Adds session isRead/isDone, tool partial content, and terminal action schemas. |
| src/vs/platform/agentHost/common/state/protocol/action-origin.generated.ts | Regenerates action origin unions and client-dispatchable map for new actions. |
| src/vs/platform/agentHost/common/state/protocol/.ahp-version | Bumps synced protocol version hash. |
| src/vs/platform/agentHost/common/remoteAgentHostService.ts | Introduces typed entry model (WebSocket/SSH/Tunnel) and raw config conversions. |
| src/vs/platform/agentHost/common/agentService.ts | Removes deprecated auth/model discovery APIs; adds session flags + new protected resource typing. |
| src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts | Registers tunnel agent host main service + IPC channel in shared process. |
| package.json | Adds dev-tunnels dependencies required for tunnel integration. |
| eslint.config.js | Allows specific dev-tunnels imports under node-only ESLint gating. |
| cli/src/tunnels/port_forwarder.rs | Blocks forwarding of the new agent-host port alongside the control port. |
| cli/src/tunnels/control_server.rs | Adds agent-host port listener and on-demand agent host proxying. |
| cli/src/tunnels/agent_host.rs | Adds reusable agent-host server lifecycle manager + proxy implementation. |
| cli/src/tunnels.rs | Exposes tunnels agent-host module. |
| cli/src/constants.rs | Adds agent-host port constant and bumps protocol version. |
| cli/src/commands/tunnels.rs | Includes agent-host port when starting launcher tunnels. |
| cli/src/commands/agent_host.rs | Refactors to use shared tunnels agent-host manager module. |
| build/.moduleignore | Strips native artifacts from websocket optional deps to avoid cross-platform packaging breaks. |
Copilot's findings
Comments suppressed due to low confidence (2)
src/vs/platform/agentHost/common/state/sessionClientState.ts:130
handleSnapshotnow acceptsITerminalState, but the implementation still treats every non-root snapshot as anISessionStateand stores it in the session maps. This will mis-handle terminal snapshots (and terminal actions aren’t reconciled anywhere in this class), so terminal subscriptions will either corrupt session state or never update correctly.
Suggested fix: either (a) extend SessionClientState with dedicated terminal state storage + a terminalReducer path (including handling terminal actions in receiveEnvelope), or (b) don’t widen the type here until terminal resources are actually supported.
handleSnapshot(resource: string, state: IRootState | ISessionState | ITerminalState, fromSeq: number): void {
this._lastSeenServerSeq = Math.max(this._lastSeenServerSeq, fromSeq);
if (resource === ROOT_STATE_URI) {
const rootState = state as IRootState;
this._confirmedRootState = rootState;
this._optimisticRootState = rootState;
this._onDidChangeRootState.fire(rootState);
} else {
const sessionState = state as ISessionState;
this._confirmedSessionStates.set(resource, sessionState);
this._optimisticSessionStates.set(resource, sessionState);
// Re-apply any pending session actions for this session
this._recomputeOptimisticSession(resource);
this._onDidChangeSessionState.fire({
session: resource,
state: this._optimisticSessionStates.get(resource)!,
});
src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHostSessionsProvider.ts:490
setReadupdates local state even when disconnected, but only dispatchessession/isReadChangedwhen_connectionis available. This can desynchronize the UI from the persisted session state.
Suggested fix: mirror the browse flow—attempt connectOnDemand before dispatching, or don’t mutate local state when disconnected (and surface an error) so read/unread changes don’t appear to succeed without being persisted.
- Files reviewed: 53/54 changed files
- Comments generated: 3
| createTerminal: async () => { | ||
| return null; | ||
| }, | ||
| disposeTerminal: async () => { | ||
| return null; | ||
| }, |
There was a problem hiding this comment.
The typed protocol now exposes createTerminal/disposeTerminal, but the server handlers currently just return null without creating/disposing anything or updating root/terminal state. This will cause clients to believe the operation succeeded while no terminal exists.
If terminals aren’t supported yet, return a JSON-RPC error (e.g. a dedicated "not implemented"/MethodNotFound error) rather than success; otherwise implement the commands (create terminal state, update root/terminalsChanged, and support subscribing to terminal URIs).
| async archiveSession(sessionId: string): Promise<void> { | ||
| const rawId = this._rawIdFromChatId(sessionId); | ||
| const cached = rawId ? this._sessionCache.get(rawId) : undefined; | ||
| if (cached && rawId) { | ||
| cached.isArchived.set(true, undefined); | ||
| this._storeArchivedState(rawId, true); | ||
| this._onDidChangeSessions.fire({ added: [], removed: [], changed: [this._chatToSession(cached)] }); | ||
| if (this._connection) { | ||
| const action = { type: ActionType.SessionIsDoneChanged as const, session: AgentSession.uri(cached.agentProvider, rawId).toString(), isDone: true }; | ||
| this._connection.dispatchAction(action, this._connection.clientId, this._connection.nextClientSeq()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| async unarchiveSession(sessionId: string): Promise<void> { | ||
| const rawId = this._rawIdFromChatId(sessionId); | ||
| const cached = rawId ? this._sessionCache.get(rawId) : undefined; | ||
| if (cached && rawId) { | ||
| cached.isArchived.set(false, undefined); | ||
| this._storeArchivedState(rawId, false); | ||
| this._onDidChangeSessions.fire({ added: [], removed: [], changed: [this._chatToSession(cached)] }); | ||
| if (this._connection) { | ||
| const action = { type: ActionType.SessionIsDoneChanged as const, session: AgentSession.uri(cached.agentProvider, rawId).toString(), isDone: false }; | ||
| this._connection.dispatchAction(action, this._connection.clientId, this._connection.nextClientSeq()); | ||
| } |
There was a problem hiding this comment.
archiveSession/unarchiveSession optimistically update local cached state even when _connection is undefined, but only dispatch the persistence action when connected. This can leave the UI showing a session as archived/unarchived even though the change will be lost on refresh/reconnect.
Suggested fix: if connectOnDemand is available, establish a connection before mutating and dispatching; otherwise fail the operation (or avoid mutating local state) when disconnected, so the UI doesn’t present a non-persisted state change.
This issue also appears on line 481 of the same file.
Brings back changes reverted in #308162
Verified build in https://dev.azure.com/monacotools/Monaco/_build/results?buildId=428418&view=results
Change was just adding the native stuff to .moduleignore. Both libraries that had native deps also have plain JS fallbacks, and specifically utf-8-validate's native stuff was just a polyfill for Node <18.