Skip to content

fix: deprecate @workspace vector search + fix @folder files not appearing in context#2698

Open
chungjac wants to merge 8 commits intomainfrom
feature/removing-at-workspace
Open

fix: deprecate @workspace vector search + fix @folder files not appearing in context#2698
chungjac wants to merge 8 commits intomainfrom
feature/removing-at-workspace

Conversation

@chungjac
Copy link
Copy Markdown
Contributor

@chungjac chungjac commented Apr 14, 2026

Merging Feature branch into main

Problem

@workspace uses vector/semantic search (ONNX, faiss, CodeSage) which is being deprecated. The qserver bundles are ~100MB due to these ML dependencies. Additionally, @folder typed context was broken — files were not appearing in context.

Solution

@workspace removal

  • Remove @workspace from context commands menu
  • Clean up dead code: queryVectorIndex, isIndexingEnabled, enableIndexing, GPU/worker/cache config, onIndexingInProgressChanged, codeSearch.ts, cwsprChatHasWorkspaceContext telemetry
  • Strip ONNX/faiss/CodeSage from qserver zips (100MB → 2.9MB per platform, all platforms now identical)
  • Remove server-side config fields: enableLocalIndexing, enableGpuAcceleration, indexWorkerThreads, indexCacheDirPath

@folder fix

  • Fix typed context bug where @folder files were not appearing in context

What still works

  • @file, @folder, @code — context commands via tree-sitter + filesystem
  • Inline completions — BM25 + repomap cross-file context
  • localProjectContextController.ts still loads indexing library, calls buildIndex('default') for repomap

Related IDE PRs

chungjac and others added 7 commits April 2, 2026 13:27
…2670)

* fix: remove @workspace from context commands menu

* fix: clean up @workspace dead code after removing from context menu

* fix: remove onIndexingInProgressChanged test
Remove all code paths related to @workspace (vector/semantic search) that
were left after the initial UI removal. This includes:

- localProjectContextController: remove queryVectorIndex, isIndexingEnabled,
  enableIndexing, GPU/worker thread/cache dir config, onIndexingInProgressChanged,
  buildIndex('all'). buildIndex now always uses 'default' (repomap only).
- configurationUtils: remove enableLocalIndexing, enableGpuAcceleration,
  indexWorkerThreads, indexCacheDirPath from config types and defaults
- localProjectContextServer: remove dead config params passed to init()
- triggerContext: remove extractProjectContext and @workspace check
- chatTelemetryController/telemetryService: remove cwsprChatHasWorkspaceContext
- Delete codeSearch.ts (never registered in toolServer, always dead code)
- Update corresponding test files
…fix merge conflicts (#2696)

* perf(amazonq): context command performance (#2682)

* perf(amazonq): cap context command payload and throttle indexing updates

- Cap context commands sent to webview at 10,000 items
- Throttle onIndexingInProgressChanged with 500ms coalescing
- Cache full item list before applying cap for reuse
- Add preservation property-based tests
- Update unit tests for throttle behavior

* chore: error

* fix: newly added files are not be loaded

* fix: bugfix

* perf: handle context commands in server

* perf: add server-side filtering for context commands in large repos

* chore: bump language-server-runtimes, runtimes-types, and mynah-ui

* chore: remove redundant debug log

* fix: filter out externally deleted files from context command results

Files deleted outside the IDE (e.g. git revert/checkout) were not
removed from the cached context commands because LSP workspace file
operation events only fire for IDE-initiated deletions. Add an
fs.existsSync check when returning results to the client so stale
entries are excluded regardless of how the file was removed.

* chore: remove debug logs from context commands and indexing paths

* fix: scope filterContextCommandsResponse to requesting tab

Previously, filter responses updated contextCommands in all tabs,
causing a search in one tab to overwrite the default list in others.
Track the originating tabId and scope the store update accordingly.

* fix: address PR review feedback for context command filtering

* fix: correct URI mapping in onDidRenameFiles handler (#2688)

* chore(release): release packages from branch main (#2689)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore: merge agentic version 1.64.0 (#2694)

* chore: bump agentic version: 1.64.0

* fix: reserve folder budget in initial context command cap (#2693)

* fix: reserve folder budget in initial context command cap

The initial sendContextCommands push is capped at 1000 items, but the
flat slice(0, 1000) starves folders when files dominate the list. In
large repos (212k+ items), the first 1000 are almost all files, so
@folder shows no children until the user types a search term.

Partition items by type and reserve 10% of the cap budget for folders
before filling the rest with files and code symbols. This ensures
@folder always has children on first load. The filter handler already
searches the full uncapped cache, so this only affects the initial push.

* test: add folder budget tests for processContextCommandUpdate

Verify that the initial context command cap reserves slots for folders:
- folders are included when items exceed the cap
- all folders included when fewer than budget
- total items don't exceed CONTEXT_COMMAND_PAYLOAD_CAP
- small payloads pass through unchanged

* fix: apply cap to empty-search filter response to preserve @folder

When onFilterContextCommands fires with an empty searchTerm (user
navigated back or cleared search), the handler was returning ALL
cached items (212k+) with no cap. This massive response overwrote
the tab's contextCommands store, and subsequent @folder clicks
showed an empty list because the store structure was inconsistent.

Apply the same cap+budget logic as processContextCommandUpdate so
the empty-search response matches the initial push structure.

* refactor: remove stale context command cache, always pull fresh from indexer

The cachedContextCommands field was a separate copy of the indexer's
data that could get out of sync — causing @folder to show empty after
searches overwrote the store, and stale items to persist after file
operations.

Remove the cache entirely. The indexer (local-indexing) is the single
source of truth. The filter handler now calls getFreshItems() on every
request, and processContextCommandUpdate receives items directly from
the indexer callbacks. The cap+budget logic is extracted into capItems()
and shared between the initial push and the empty-search filter path.

* fix: restore base context commands on empty filter instead of round-tripping

After a search filtered the context commands, the store held the
filtered set. Subsequent @Folder/@file clicks read from this stale
store and showed only the previous search results.

When onContextCommandFilter fires with an empty searchTerm (user
cleared search or navigated back), restore contextCommandGroups
directly to the store instead of sending a request to the server.
This keeps the store consistent with the base set and avoids the
round-trip latency.

* fix: prevent sendContextCommands from resetting active filter tab

sendContextCommands is a server push that fires on indexing changes
and overwrites contextCommands for ALL tabs. This reset the picker
while the user was browsing @Folder/@file sub-menus, causing the
6-10 second snap-back to the main menu.

Skip the store update for tabs with an active filter session
(lastFilterTabId). Clear the guard on tab change, tab remove,
and chat prompt submission so it doesn't persist.

* fix: restore base contextCommands after filter response via microtask

filterContextCommandsResponse updates the store with filtered results
so the picker's store listener can refresh. But this left the store
with stale filtered data, causing @Folder/@file to show previous
search results on subsequent navigation.

After updating the store for the picker, schedule a microtask to
restore contextCommandGroups (the base set) back to the store. The
picker captures filtered items synchronously during updateStore, so
the microtask restore doesn't affect the current display but ensures
sub-menu navigation reads from the full base set.

* fix: restore filterContextCommandsResponse store update

Now that mynah-ui preserves baseContextCommands separately from the
store's contextCommands, the filter response can safely update the
store again. The picker uses the filtered data for display while
sub-menu navigation reads from the base snapshot.

* chore: patch

* test: cover getFreshItems and registerFilterHandler empty-search

- 3 tests for getFreshItems: getInstance reject, getContextCommandItems
  reject, success path.
- 2 tests for registerFilterHandler empty-search path: applies capItems
  folder budget when called with empty searchTerm and when called with
  a whitespace-only searchTerm.

* fix: reserve code symbol budget in capItems

The previous capItems partitioned items into folders vs nonFolders,
where nonFolders included both files AND code symbols sharing the same
900-slot budget. In file-heavy repos (e.g. Linux kernel: 212k+ items)
files dominate the input order so code symbols are silently dropped
from the initial picker view, even though typing a search term still
finds them via the non-empty filter path.

Replace the 2-way partition with a 3-way 10/10/80 split (folders /
code / files). Slack from an under-filled folder or code budget flows
into the file budget via the subtraction below.

Mirrors the existing folder-budget fix pattern. Add 5 tests:
- code symbols included when items exceed cap
- all code symbols preserved when fewer than budget
- 100/100/800 split when all three categories overflow
- code not starved when files come first in input (regression case)
- empty-search filter handler also reserves the code budget

* fix: bump context command payload cap from 1000 to 2000

Double both CONTEXT_COMMAND_PAYLOAD_CAP and MAX_FILTER_RESULTS so the
initial picker view and the typed-search filter response can return up
to 2000 items each. The 10/10/80 budget split now yields 200 folders /
200 code / 1600 files instead of 100 / 100 / 800.

The bottleneck under load is fs.existsSync over the full ~212k indexer
item set, not the cap; doubling the cap adds <50KB to the LSP payload
and a few ms to map/render but is otherwise negligible. mynah-ui's
DetailedListWrapper virtualizes by visible block, so 2x items don't
add proportional render cost.

Update all 8 affected test assertions to the new expected counts.

* chore: bump @aws/mynah-ui to ^4.40.1

Pulls in the latest mynah-ui patch release. See
https://github.com/aws/mynah-ui/releases/tag/v4.40.1

* fix: switch capItems split to 500/500/1000 (25/25/50)

Folders and code symbols each get 25% of the cap (500), files get 50%
(1000). Previously the 10/10/80 split (200/200/1600) tilted heavily
toward files; the new split gives folders and code symbols a fair
share of the initial picker view in folder- and symbol-rich repos.

This only affects the **empty-search** picker view (no search term).
The non-empty filter path still scores against the full fresh indexer
set in registerFilterHandler — typing a search term will find any
folder, file, or code symbol regardless of whether it fit into the cap.

Test inputs scaled up to 600-800 per category so the new 500-slot
budget is actually exercised. All 24 tests pass.

* test: drop stale cachedContextCommands assertion in preservation test

The property-based test 'processContextCommandUpdate sends all items
and caches them for small payloads' has been failing in CI since
commit 79e6e75 (refactor: remove stale context command cache, always
pull fresh from indexer). That refactor deleted the
cachedContextCommands field, but this preservation test still asserted
that (provider as any).cachedContextCommands === items, which now
always evaluates to undefined !== items and fails on the empty-array
counterexample.

Drop the cache assertion. The test now verifies the still-meaningful
contract: processContextCommandUpdate dispatches exactly one
sendContextCommands call with a contextCommandGroups payload.

Local repro: npx mocha --require ts-node/register
'src/language-server/agenticChat/context/contextCommandsProvider*.test.ts'
→ 28 passing.

---------

Co-authored-by: aws-toolkit-automation <>

* fix: typed @folder context not showing files in collapsible list

When typing @folder (non-pinned), the expanded file entries were not
appearing in the context list. The ordering logic looked up the folder
path in docMap, but docMap is keyed by individual file paths. Added a
fallback for folder items that matches all child file entries by path
prefix.

Pinned @folder was unaffected because it bypasses the docMap lookup.

* chore: fix prettier formatting

---------

Co-authored-by: Will Lo <96078566+Will-ShaoHua@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Remove ONNX, faiss, and CodeSage model from qserver bundles. The indexing
library no longer contains vector/semantic search code since @workspace is
being removed. Each qserver zip drops from ~100MB to ~2.9MB.

@file, @folder, @code continue to work (tree-sitter + BM25).
All 5 platform zips are now identical (no native binaries).
* perf(amazonq): context command performance (#2682)

* perf(amazonq): cap context command payload and throttle indexing updates

- Cap context commands sent to webview at 10,000 items
- Throttle onIndexingInProgressChanged with 500ms coalescing
- Cache full item list before applying cap for reuse
- Add preservation property-based tests
- Update unit tests for throttle behavior

* chore: error

* fix: newly added files are not be loaded

* fix: bugfix

* perf: handle context commands in server

* perf: add server-side filtering for context commands in large repos

* chore: bump language-server-runtimes, runtimes-types, and mynah-ui

* chore: remove redundant debug log

* fix: filter out externally deleted files from context command results

Files deleted outside the IDE (e.g. git revert/checkout) were not
removed from the cached context commands because LSP workspace file
operation events only fire for IDE-initiated deletions. Add an
fs.existsSync check when returning results to the client so stale
entries are excluded regardless of how the file was removed.

* chore: remove debug logs from context commands and indexing paths

* fix: scope filterContextCommandsResponse to requesting tab

Previously, filter responses updated contextCommands in all tabs,
causing a search in one tab to overwrite the default list in others.
Track the originating tabId and scope the store update accordingly.

* fix: address PR review feedback for context command filtering

* fix: correct URI mapping in onDidRenameFiles handler (#2688)

* chore(release): release packages from branch main (#2689)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore: merge agentic version 1.64.0 (#2694)

* chore: bump agentic version: 1.64.0

* fix: reserve folder budget in initial context command cap (#2693)

* fix: reserve folder budget in initial context command cap

The initial sendContextCommands push is capped at 1000 items, but the
flat slice(0, 1000) starves folders when files dominate the list. In
large repos (212k+ items), the first 1000 are almost all files, so
@folder shows no children until the user types a search term.

Partition items by type and reserve 10% of the cap budget for folders
before filling the rest with files and code symbols. This ensures
@folder always has children on first load. The filter handler already
searches the full uncapped cache, so this only affects the initial push.

* test: add folder budget tests for processContextCommandUpdate

Verify that the initial context command cap reserves slots for folders:
- folders are included when items exceed the cap
- all folders included when fewer than budget
- total items don't exceed CONTEXT_COMMAND_PAYLOAD_CAP
- small payloads pass through unchanged

* fix: apply cap to empty-search filter response to preserve @folder

When onFilterContextCommands fires with an empty searchTerm (user
navigated back or cleared search), the handler was returning ALL
cached items (212k+) with no cap. This massive response overwrote
the tab's contextCommands store, and subsequent @folder clicks
showed an empty list because the store structure was inconsistent.

Apply the same cap+budget logic as processContextCommandUpdate so
the empty-search response matches the initial push structure.

* refactor: remove stale context command cache, always pull fresh from indexer

The cachedContextCommands field was a separate copy of the indexer's
data that could get out of sync — causing @folder to show empty after
searches overwrote the store, and stale items to persist after file
operations.

Remove the cache entirely. The indexer (local-indexing) is the single
source of truth. The filter handler now calls getFreshItems() on every
request, and processContextCommandUpdate receives items directly from
the indexer callbacks. The cap+budget logic is extracted into capItems()
and shared between the initial push and the empty-search filter path.

* fix: restore base context commands on empty filter instead of round-tripping

After a search filtered the context commands, the store held the
filtered set. Subsequent @Folder/@file clicks read from this stale
store and showed only the previous search results.

When onContextCommandFilter fires with an empty searchTerm (user
cleared search or navigated back), restore contextCommandGroups
directly to the store instead of sending a request to the server.
This keeps the store consistent with the base set and avoids the
round-trip latency.

* fix: prevent sendContextCommands from resetting active filter tab

sendContextCommands is a server push that fires on indexing changes
and overwrites contextCommands for ALL tabs. This reset the picker
while the user was browsing @Folder/@file sub-menus, causing the
6-10 second snap-back to the main menu.

Skip the store update for tabs with an active filter session
(lastFilterTabId). Clear the guard on tab change, tab remove,
and chat prompt submission so it doesn't persist.

* fix: restore base contextCommands after filter response via microtask

filterContextCommandsResponse updates the store with filtered results
so the picker's store listener can refresh. But this left the store
with stale filtered data, causing @Folder/@file to show previous
search results on subsequent navigation.

After updating the store for the picker, schedule a microtask to
restore contextCommandGroups (the base set) back to the store. The
picker captures filtered items synchronously during updateStore, so
the microtask restore doesn't affect the current display but ensures
sub-menu navigation reads from the full base set.

* fix: restore filterContextCommandsResponse store update

Now that mynah-ui preserves baseContextCommands separately from the
store's contextCommands, the filter response can safely update the
store again. The picker uses the filtered data for display while
sub-menu navigation reads from the base snapshot.

* chore: patch

* test: cover getFreshItems and registerFilterHandler empty-search

- 3 tests for getFreshItems: getInstance reject, getContextCommandItems
  reject, success path.
- 2 tests for registerFilterHandler empty-search path: applies capItems
  folder budget when called with empty searchTerm and when called with
  a whitespace-only searchTerm.

* fix: reserve code symbol budget in capItems

The previous capItems partitioned items into folders vs nonFolders,
where nonFolders included both files AND code symbols sharing the same
900-slot budget. In file-heavy repos (e.g. Linux kernel: 212k+ items)
files dominate the input order so code symbols are silently dropped
from the initial picker view, even though typing a search term still
finds them via the non-empty filter path.

Replace the 2-way partition with a 3-way 10/10/80 split (folders /
code / files). Slack from an under-filled folder or code budget flows
into the file budget via the subtraction below.

Mirrors the existing folder-budget fix pattern. Add 5 tests:
- code symbols included when items exceed cap
- all code symbols preserved when fewer than budget
- 100/100/800 split when all three categories overflow
- code not starved when files come first in input (regression case)
- empty-search filter handler also reserves the code budget

* fix: bump context command payload cap from 1000 to 2000

Double both CONTEXT_COMMAND_PAYLOAD_CAP and MAX_FILTER_RESULTS so the
initial picker view and the typed-search filter response can return up
to 2000 items each. The 10/10/80 budget split now yields 200 folders /
200 code / 1600 files instead of 100 / 100 / 800.

The bottleneck under load is fs.existsSync over the full ~212k indexer
item set, not the cap; doubling the cap adds <50KB to the LSP payload
and a few ms to map/render but is otherwise negligible. mynah-ui's
DetailedListWrapper virtualizes by visible block, so 2x items don't
add proportional render cost.

Update all 8 affected test assertions to the new expected counts.

* chore: bump @aws/mynah-ui to ^4.40.1

Pulls in the latest mynah-ui patch release. See
https://github.com/aws/mynah-ui/releases/tag/v4.40.1

* fix: switch capItems split to 500/500/1000 (25/25/50)

Folders and code symbols each get 25% of the cap (500), files get 50%
(1000). Previously the 10/10/80 split (200/200/1600) tilted heavily
toward files; the new split gives folders and code symbols a fair
share of the initial picker view in folder- and symbol-rich repos.

This only affects the **empty-search** picker view (no search term).
The non-empty filter path still scores against the full fresh indexer
set in registerFilterHandler — typing a search term will find any
folder, file, or code symbol regardless of whether it fit into the cap.

Test inputs scaled up to 600-800 per category so the new 500-slot
budget is actually exercised. All 24 tests pass.

* test: drop stale cachedContextCommands assertion in preservation test

The property-based test 'processContextCommandUpdate sends all items
and caches them for small payloads' has been failing in CI since
commit 79e6e75 (refactor: remove stale context command cache, always
pull fresh from indexer). That refactor deleted the
cachedContextCommands field, but this preservation test still asserted
that (provider as any).cachedContextCommands === items, which now
always evaluates to undefined !== items and fails on the empty-array
counterexample.

Drop the cache assertion. The test now verifies the still-meaningful
contract: processContextCommandUpdate dispatches exactly one
sendContextCommands call with a contextCommandGroups payload.

Local repro: npx mocha --require ts-node/register
'src/language-server/agenticChat/context/contextCommandsProvider*.test.ts'
→ 28 passing.

---------

Co-authored-by: aws-toolkit-automation <>

---------

Co-authored-by: Will Lo <96078566+Will-ShaoHua@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@chungjac chungjac requested a review from a team as a code owner April 14, 2026 23:07
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 14, 2026

Codecov Report

❌ Patch coverage is 44.82759% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.45%. Comparing base (dcd7829) to head (b2ab032).

Files with missing lines Patch % Lines
...r/agenticChat/context/additionalContextProvider.ts 38.46% 8 Missing ⚠️
...sperer/src/shared/localProjectContextController.ts 11.11% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2698      +/-   ##
==========================================
- Coverage   60.51%   60.45%   -0.07%     
==========================================
  Files         279      278       -1     
  Lines       66515    66065     -450     
  Branches     4270     4223      -47     
==========================================
- Hits        40250    39937     -313     
+ Misses      26180    26044     -136     
+ Partials       85       84       -1     
Flag Coverage Δ
unittests 60.45% <44.82%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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