Skip to content

Lift customization items into a single observable model#312463

Merged
joshspicer merged 3 commits intomainfrom
agents/remove-debt-customization-counts
Apr 25, 2026
Merged

Lift customization items into a single observable model#312463
joshspicer merged 3 commits intomainfrom
agents/remove-debt-customization-counts

Conversation

@joshspicer
Copy link
Copy Markdown
Member

Removes debt where the sidebar Customizations widget (Agents app) computed per-section counts via a parallel discovery code path (customizationCounts.ts) that diverged from the actual Customizations editor's data — e.g. when a ChatSessionCustomizationProvider or AHP customization was active, the badges showed the wrong number.

Approach

Introduces IAICustomizationItemsModel — a singleton owning the per-active-harness ProviderCustomizationItemSource cache and exposing per-section IObservable<readonly IAICustomizationListItem[]>. Both the editor list widget and sidebar surfaces (per-link badges + header total) read from the same observables, so counts cannot diverge from what the editor shows.

Inspired by #312398.

Changes

  • New aiCustomizationItemsModel.ts (+ unit tests) — single source of truth, registered as a Delayed singleton.
  • Editor aiCustomizationListWidget.ts + aiCustomizationManagementEditor.ts: consume the model via autoruns. setSection / refresh are now sync; the per-section count autoruns replace the old promptsSectionCountScheduler + 4 prompts-service event listeners.
  • Sidebar CustomizationLinkViewItem (customizationsToolbar.contribution.ts): single autorun over model.getCount(modelSection) / mcpService.servers / agentPluginService.plugins. ICustomizationItemConfig.promptTypemodelSection.
  • Sidebar AICustomizationShortcutsWidget header total: one derived summing all section counts + MCP + plugins.
  • Deletes customizationCounts.ts and its test.
  • Updates aiCustomizationShortcutsWidget.fixture.ts to mock just IAICustomizationItemsModel instead of the prior constellation of services.
  • Updates AI_CUSTOMIZATIONS.md.

McpServers / Plugins still use their own service observables directly — those already had a single discovery path.

Removes debt where the sidebar 'Customizations' widget computed per-section
counts via a parallel discovery code path (customizationCounts.ts) that
diverged from the actual Customizations editor's data (e.g. when a
ChatSessionCustomizationProvider or AHP customization was active).

Introduces  a singleton owning the per-active-IAICustomizationItemsModel
harness ProviderCustomizationItemSource cache and exposing per-section
IObservable<readonly IAICustomizationListItem[]>. Both the editor list
widget and sidebar surfaces (per-link badges + header total) now read from
the same observables, so counts cannot diverge from what the editor shows.

- New: aiCustomizationItemsModel.ts (+ unit tests)
- Editor list widget + management editor: consume the model via autoruns
- Sidebar CustomizationLinkViewItem: single autorun over the model /
  IMcpService.servers / IAgentPluginService.plugins
- AICustomizationShortcutsWidget header total: derived sum
- Deletes customizationCounts.ts and its test
- Updates fixture and AI_CUSTOMIZATIONS.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 25, 2026 00:19
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 25, 2026

Screenshot Changes

Base: 5886d860 Current: 678e3cf8

Changed (2)

chat/aiCustomizations/aiCustomizationListWidget/InstructionsTabWithItems/Dark
Before After
before after
chat/aiCustomizations/aiCustomizationListWidget/InstructionsTabWithItems/Light
Before After
before after

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

Unifies AI Customizations item discovery/counting behind a single IAICustomizationItemsModel so the management editor’s lists and the Sessions sidebar badges/header total cannot diverge across different harness providers.

Changes:

  • Introduces AICustomizationItemsModel (delayed singleton) that owns the per-harness item-source cache and exposes per-section observables for items and counts.
  • Refactors the Customizations management editor + list widget and Sessions sidebar badges/header total to read from the model’s observables.
  • Removes the legacy Sessions-side customizationCounts.ts counting utilities and updates tests/fixtures/docs accordingly.
Show a summary per file
File Description
src/vs/workbench/contrib/chat/test/browser/aiCustomization/aiCustomizationListWidget.test.ts Updates widget disposal test strategy to stub the new items model.
src/vs/workbench/contrib/chat/test/browser/aiCustomization/aiCustomizationItemsModel.test.ts Adds unit tests for the new model’s caching/refetch behavior.
src/vs/workbench/contrib/chat/browser/chat.contribution.ts Ensures the items model singleton is registered/loaded.
src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagementEditor.ts Replaces per-section count refresh logic with autoruns over model counts; sync setSection/refresh calls.
src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts Switches the list widget to bind to per-section model observables rather than owning its own fetch pipeline.
src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationItemsModel.ts New: single source of truth for harness-driven customization items and counts (with per-descriptor source cache).
src/vs/sessions/contrib/sessions/test/browser/customizationCounts.test.ts Deletes tests for the removed Sessions-side counting utilities.
src/vs/sessions/contrib/sessions/test/browser/aiCustomizationShortcutsWidget.fixture.ts Simplifies fixture to mock only IAICustomizationItemsModel for counts.
src/vs/sessions/contrib/sessions/browser/customizationsToolbar.contribution.ts Sidebar per-link badge counts now come from the items model (plus MCP/plugins).
src/vs/sessions/contrib/sessions/browser/customizationCounts.ts Deletes legacy parallel counting implementation.
src/vs/sessions/contrib/sessions/browser/aiCustomizationShortcutsWidget.ts Header total now derived from model section counts + MCP + plugins.
src/vs/sessions/AI_CUSTOMIZATIONS.md Updates documentation to describe the new single-path counting model.

Copilot's findings

  • Files reviewed: 12/12 changed files
  • Comments generated: 3

Comment thread src/vs/sessions/contrib/sessions/browser/aiCustomizationShortcutsWidget.ts Outdated
joshspicer and others added 2 commits April 25, 2026 08:43
- Make items model lazy: sections only fetch on first read, avoiding the
  5x provider enumeration on construction. Source.onDidChange / harness
  switch / workspace change refetch only sections that have already been
  observed.
- Cache sources by descriptor identity (not id) and prune entries whose
  descriptor is no longer in availableHarnesses. Fixes stale binding when
  an external harness re-registers under the same id.
- Cache per-section count derived in the constructor (no allocation per
  call).
- Add IAICustomizationItemsModel.whenSectionLoaded(section) so editor's
  setSection (now async again) can await the first  keeps thefetch
  screenshot fixture deterministic.
- Sidebar header total now sums over CUSTOMIZATION_ITEMS (the visible
  links) instead of every prompts-based section, so it cannot exceed the
  sum of per-link badges. Excludes Prompts which the sidebar does not
  surface.
- Wrap items-model unit tests in a sub-suite so per-test teardown disposes
  before the leak-check teardown runs. Add coverage for lazy fetching and
  descriptor re-registration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The list widget now consumes IAICustomizationItemsModel; the fixture was
still injecting only the underlying services and so failed to instantiate
the widget. Register the real AICustomizationItemsModel (it transparently
fetches through the existing prompts-service mock) and add the missing
mock methods (findAgentSkills, getPromptSlashCommands, getHooks,
getSkillUIIntegrations) that the model's discovery path exercises.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@joshspicer joshspicer marked this pull request as ready for review April 25, 2026 20:52
@joshspicer joshspicer enabled auto-merge (squash) April 25, 2026 20:53
@joshspicer joshspicer merged commit fc15846 into main Apr 25, 2026
26 checks passed
@joshspicer joshspicer deleted the agents/remove-debt-customization-counts branch April 25, 2026 21:48
@vs-code-engineering vs-code-engineering Bot added this to the 1.118.0 milestone Apr 25, 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