feat: only load chat/notebook/mcp when their service overrides are used - #830
Merged
CGNonofr merged 6 commits intoSep 29, 2026
Merged
Conversation
Search, terminal decorations, SCM, tasks, getting started and the extension host only needed a type, a lazily-used class, a command/tool id or a small helper from chat/notebook, but imported them from modules that load most of the chat implementation or the notebook editor. The same goes for the missing CustomizationHarnessService, which only needed a descriptor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eir service override The extension service override was loading every main thread participant, including the chat, notebook and mcp ones along with their implementation. They are now loaded by their own service override. As the extension host requires every main thread participant to be registered, an inert implementation is registered for the missing ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…override Fail the build when too much of chat/notebook/mcp is loaded without their service override, or when an extension host main thread participant is not imported anymore (it would silently be replaced by an inert implementation). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CGNonofr
reviewed
Sep 28, 2026
CGNonofr
left a comment
Contributor
There was a problem hiding this comment.
Thanks! it looks quite promising!
…participants Replace the generic proxy with implementations of the chat, language model, notebook and mcp MainThread shapes, like the missing services: calls that are only notifications do nothing, queries return nothing, and actions are unsupported. They are only registered for those ids, when nothing else did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A participant that isn't imported anymore is no longer silently replaced by an inert implementation: without a missing implementation for it, the extension host fails to start. The contribution check from #831 also detects a participant left in extensionHost.contribution. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
They are only needed with the extension host, so they are now imported by the extensions service override instead of living in missing-services. The Unsupported decorator moves to tools so both can use it, and the decorator check covers the new module. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CGNonofr
self-requested a review
September 29, 2026 08:05
CGNonofr
approved these changes
Sep 29, 2026
|
🎉 This PR is included in version 37.2.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follows up on #827 and #828.
Problem
A workbench that doesn't use the chat, notebook or mcp service overrides still loads most of their implementation. #828 split the extension host participants, but that turned out to be only a small part of it: most of it was loaded by core code (search, terminal, SCM, tasks, getting started, the extension host...) that only needed a type, a command id or a small helper, but imported it from a module that loads the whole chat implementation or notebook editor.
Measured with the build's own module graph (all entry points except the chat, notebook, mcp, interactive, ai, speech and welcome service overrides):
Changes
0109-refactor-avoid-runtime-dependencies-from-core-on-cha.patch: small changes at the call sites, each one keeping the behavior:searchResult: type-only cast instead ofinstanceof NotebookEditorWidget(onlyNotebookEditorWidgetregisters itself in the notebook editor service)searchView: compare the editor id withNOTEBOOK_EDITOR_IDinstead ofinstanceof NotebookEditor(nothing extends it)decorationAddon: lazyimport()ofTerminalContext, only used when attaching a command to chatchatConstantsinstead ofchatActionsagentSessionsWelcomeInputcoerceImageBufferand 3 builtin tool ids moved to dependency-free modules (re-exported from their previous location)0110-refactor-split-extension-host-contribution-per-featu.patch: as suggested in #828,extensionHost.base.contribution+extensionHost.{chat,notebook,mcp}.contribution, withextensionHost.contributionstill importing all of them. The feature ones are imported by their service override.Missing main thread participants (
service-override/tools/missingMainThreadCustomers, imported by the extensions service override; theUnsupporteddecorator moved frommissing-servicestotoolsso both use it, andcheck-unsupported-decoratorcovers both): the extension host requires everyMainContextproxy to be registered, and some extHost implementations call the main thread when they are constructed (e.g.ExtHostLanguageModelToolscalls$getTools()). So, like the missing services, there are typed implementations of the 16 chat/language model/notebook/mcpMainThread*Shapes: notifications and registrations do nothing, queries return nothing ([]/false), and actions (invoking a tool, opening a notebook, mcp tokens...) are@Unsupported. They are registered only for those ids and only when nothing else registered them, without depending on the import order (unnamed customers are instantiated after the named ones, and a real implementation set later replaces it).missing-services:CustomizationHarnessServiceno longer callscreateVSCodeHarnessDescriptor, which alone loaded ~480KB of chat.Build check (
feature-isolation-checkrollup plugin): fails when more than 1000KB of chat/notebook/mcp is loaded without their service override, and always prints the 20 heaviest imports responsible, so a regression after a VSCode update points to the exact import.A participant lost while rebasing 0110 makes the extension host fail to start (there is no missing implementation for it), and one left in
extensionHost.contributionis detected bycheck-workbench-contributionsfrom #831.Behavior changes
Without the chat/lm service overrides, queries of the corresponding extension API return nothing instead of throwing: e.g.
vscode.lm.selectChatModels()resolves with[]instead of rejecting with "Unsupported". Actions (e.g.vscode.lm.invokeTool,vscode.workspace.openNotebookDocument) still reject with "Unsupported".Known remaining (~911KB)
Not addressed because they are actual dependencies rather than misplaced imports:
dictationSession,chatSpeechToTextService), also used bymissing-servicesforChatSpeechToTextStateChatOutline,chatViewModel)extHostTypeConverters/extHostLanguageModels->languageModelsmainThreadEditorTabs->chatEditorInput(tab input kinds)Testing
npm run buildsteps (compile, rollup plugins, default extensions, language packs, monaco languages), lint,check-unsupported-decorator, commitlintselectChatModels/toolsare empty, registrations work,invokeToolandopenNotebookDocumentreject with "Unsupported", no console error (note: the demo dev server pre-bundles every local package, including the unused service overrides, so this has to be checked on a production build)The 0109 changes could also be proposed to microsoft/vscode, which would remove most of the patch.
🤖 Generated with Claude Code