Skip to content

agentHost: resolve per-chat effective working directory in session projection#323950

Merged
sandy081 merged 5 commits into
mainfrom
agents/mc-chataddr-t7-per-chat-context
Jul 1, 2026
Merged

agentHost: resolve per-chat effective working directory in session projection#323950
sandy081 merged 5 commits into
mainfrom
agents/mc-chataddr-t7-per-chat-context

Conversation

@sandy081

@sandy081 sandy081 commented Jul 1, 2026

Copy link
Copy Markdown
Member

Task mc-CHATADDR-T7 — per-chat resolved session-context view

Orthogonal cleanup: every chat handle should expose its effective session context (resolved working directory, active client, auth/MCP + customization scope, config) so no operational code path has to walk back to the session to read shared state.

Finding

The per-chat context projection already largely exists: mergeSessionWithDefaultChat(session, chat) spreads the full SessionState onto each chat and is already used for default, peer, and subagent chats (AgentHostStateManager.getSessionState, and the workbench handler). Because SessionState owns activeClients / config / customizations (no per-chat override), those are already resolved correctly for every chat.

Delta: the protocol lets a chat override the session working directory (ChatState.workingDirectory, e.g. to give a subordinate chat its own git worktree), but the projection did ...session and never layered that override. Operational consumers read the effective cwd through this view — agentHostChangesetService, agentHostCommitOperationHandler, agentHostDiscardChangesOperationHandler, agentHostGitStateService, agentHostPullRequestOperationHandler, agentHostSyncOperationHandler, and agentService all read getSessionState(...)?.workingDirectory — so a chat with its own worktree incorrectly reported the session default.

Change

  • mergeSessionWithDefaultChat now resolves workingDirectory: chat?.workingDirectory ?? session.workingDirectory, making it a true per-chat effective session-context projection for all chats.
  • Generalized the docs on the projection and ISessionWithDefaultChat from "default chat" to per-chat effective context.
  • Added unit tests (override wins, fallback to session default, fallback when chat state absent).

Pure orchestrator-side projection — no wire-protocol, IAgent, or persisted-shape change; confined to src/vs/platform/agentHost.

Validation

  • node build/next/index.ts transpile — pass
  • ./scripts/test.sh --grep "AgentService|AgentHostStateManager|CopilotAgent|ClaudeAgent|CodexAgent" — 640 passing (3 new)
  • npm run typecheck-client — pass
  • npm run valid-layers-check — pass

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

sandy081 and others added 3 commits July 1, 2026 22:59
…on param

PART 1: remove the unreachable claude.chats legacy peer-chat migration
(listLegacyChats, _readPersistedChats, _META_CHATS and the two dead
fallback call sites). Copilot's copilot.chats migration and the
orchestrator's generic migration are unchanged.

PART 2A: drop the redundant session parameter from IAgentChats.createChat
and fork. Each agent derives the parent session from the chat URI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restructure the shared AgentSessionEntry so a session's default (main)
chat lives in the SAME per-session chat map as its peers, keyed by its
default-chat URI. Send/abort/model/agent/history now resolve any chat
via one uniform getChat lookup with no default-vs-peer storage split.

- agentPeerChats.ts: single _chats map + _defaultChatKey; getChat is the
  uniform lookup; defaultChat/setDefaultChat/clearDefaultChat replace the
  separate default-session slot; peer accessors read the same map.
- Claude/Copilot seed the default chat into the map (setDefaultChat) and
  read it via defaultChat; _findChat is a single uniform lookup.
- Two lifecycle guards kept at the session boundary: createSession seeds
  the default entry; disposeChat/createChat refuse the default chat.
- Codex (single-chat) unchanged; still resolves through the session URI.

No protocol/state changes; behavior identical (Agent* suites green).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ojection

Generalize the mergeSessionWithDefaultChat projection so a chat's resolved
session-context view (working directory, active clients, config,
customizations/MCP scope, …) applies to ALL chats, not just the default one.

The projection already spreads the full SessionState onto every chat, but it
ignored ChatState.workingDirectory — a per-chat override the protocol allows so
a subordinate/peer chat can run in its own git worktree. Operational consumers
(changeset/commit/discard/git/PR/sync services + agentService) read the effective
cwd via getSessionState(...)?.workingDirectory, so a chat with its own worktree
incorrectly reported the session default. Layer chat.workingDirectory over the
session default in the projection so no code path has to walk back to the session.

Pure orchestrator-side projection: no wire-protocol, IAgent, or persisted-shape
change. Docs generalized from "default chat" to per-chat effective context.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 21:54

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 pull request improves the agent host’s per-chat “effective session context” projection by ensuring a chat-level working directory override is reflected in the merged session+chat view. It also updates the multi-chat agent surface to be chat-addressed (deriving the parent session from the chat URI) and adjusts agent implementations, tests, and architecture docs accordingly.

Changes:

  • Fix mergeSessionWithDefaultChat to layer ChatState.workingDirectory over SessionState.workingDirectory, making the projection reflect the effective per-chat working directory.
  • Update IAgentChats.createChat / fork to be chat-addressed (drop explicit session parameter) and adapt agents + orchestrator plumbing to the new signature.
  • Add unit tests covering working directory override vs fallback behavior.
Show a summary per file
File Description
src/vs/platform/agentHost/test/node/mockAgent.ts Updates mock agent chat APIs to match the new chat-addressed IAgentChats shape.
src/vs/platform/agentHost/test/node/copilotAgent.test.ts Updates Copilot agent tests to use chat-addressed create/fork and revised session-entry structure.
src/vs/platform/agentHost/test/node/claudeAgent.test.ts Updates Claude agent tests for chat-addressed create/fork and default-chat entry changes.
src/vs/platform/agentHost/test/node/agentService.test.ts Updates dispatcher tests to derive session from chat URIs for create/fork assertions.
src/vs/platform/agentHost/test/node/agentHostStateManager.test.ts Adds tests verifying per-chat working directory override behavior in session projection.
src/vs/platform/agentHost/node/copilot/copilotAgent.ts Refactors Copilot agent chat creation/forking to derive session from chat URI and unifies chat storage access.
src/vs/platform/agentHost/node/codex/codexAgent.ts Adjusts Codex agent to the new IAgentChats signature (still single-chat only).
src/vs/platform/agentHost/node/claude/claudeAgent.ts Refactors Claude agent to derive session from chat URI, unify chat lookup, and drop legacy peer-chat catalog reading.
src/vs/platform/agentHost/node/agentService.ts Updates orchestrator-side chat creation plumbing to call providers with chat URI only.
src/vs/platform/agentHost/node/agentPeerChats.ts Refactors shared per-session chat container to a single uniform chat map (default + peers).
src/vs/platform/agentHost/MULTI_CHAT_ARCHITECTURE.md Updates architecture documentation to reflect chat-addressed calls and legacy migration expectations.
src/vs/platform/agentHost/common/state/sessionState.ts Fixes session+chat projection to apply chat working directory override; updates docs accordingly.
src/vs/platform/agentHost/common/agentService.ts Updates IAgentChats interface to remove explicit session parameter for create/fork.

Review details

  • Files reviewed: 13/13 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread src/vs/platform/agentHost/test/node/mockAgent.ts Outdated
Comment thread src/vs/platform/agentHost/test/node/mockAgent.ts Outdated
sandy081 and others added 2 commits July 2, 2026 00:01
…-per-chat-context

# Conflicts:
#	src/vs/platform/agentHost/MULTI_CHAT_ARCHITECTURE.md
Address CCR feedback: createChat/fork resolved the session via
_resolveChatTarget but passed the original chat argument, so a default-chat
call (session URI) would use the session URI instead of the resolved
default-chat channel URI. Destructure and pass the resolved { session, chat }
to match the other chat-addressed methods in the mock.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sandy081
sandy081 enabled auto-merge (squash) July 1, 2026 22:26
@sandy081 sandy081 self-assigned this Jul 1, 2026
@sandy081 sandy081 added this to the 1.128.0 milestone Jul 1, 2026

@TylerLeonhardt TylerLeonhardt 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.

Approving from a security perspective to not slow down but there's feedback I'll give async

@sandy081
sandy081 merged commit b7b8a80 into main Jul 1, 2026
29 checks passed
@sandy081
sandy081 deleted the agents/mc-chataddr-t7-per-chat-context branch July 1, 2026 22:47
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