Skip to content

feat: delegate lsp to handle context command filtering - #743

Merged
Will-ShaoHua merged 1 commit into
Amazon-Q-Developer:mainfrom
Will-ShaoHua:perf
Mar 31, 2026
Merged

Will-ShaoHua merged 1 commit into
Amazon-Q-Developer:mainfrom
Will-ShaoHua:perf

Conversation

@Will-ShaoHua

@Will-ShaoHua Will-ShaoHua commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Problem

In large repos (80k+ files), the @ context picker in Amazon Q's chat UI becomes unusable. The root cause is that the server sends all context command items to the webview in a single sendContextCommands notification. This triggers:

  • Deep-clone overhead in mynah-ui's store (getValue() deep-clones the entire array)
  • O(n) local filtering over 80k items on every keystroke
  • Massive serialization cost when passing data between server and webview

Result: multi-second freezes when pressing @ or typing in the context picker.

Solution

Keep all items cached on the server. Only send a capped subset (≤1000 items) to the webview for the initial @ press. When the user types, a new filterContextCommands LSP request is sent to the server, which scores and filters all 80k items and returns the top 1000 matches.

Flow

User presses @ in mynah-ui
  → Shows capped 1000 items from store (instant)

User types "@fo"
  → Local filter runs immediately over capped 1000 items (instant feedback)
  → mynah-ui dispatches CONTEXT_COMMAND_FILTER event (debounced 200ms)
  → chat-client receives callback, sends filterContextCommands request to server
  → Server scores all 80k cached items, sorts by score, returns top ≤1000 matches
  → chat-client receives response, calls updateStore({ contextCommands: results })
  → mynah-ui re-renders the picker with server-filtered results

New file created
  → Indexer fires onContextItemsUpdated with updated list
  → processContextCommandUpdate caches full list, prioritizes new items in capped payload
  → sendContextCommands pushes updated capped set to webview
  → Server-side filter also sees the new file in the full cache
Screen.Recording.2026-03-31.at.11.25.53.AM.mov

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@Will-ShaoHua
Will-ShaoHua requested a review from a team as a code owner March 31, 2026 06:06

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

Would be great if you can attach a demo/screenshot of performan improvement or provide a build to test.

@Will-ShaoHua

Copy link
Copy Markdown
Contributor Author

Would be great if you can attach a demo/screenshot of performan improvement or provide a build to test.

yep makes sense, provided via slack.

@Will-ShaoHua
Will-ShaoHua merged commit 8836c33 into Amazon-Q-Developer:main Mar 31, 2026
4 checks passed
@Will-ShaoHua
Will-ShaoHua deleted the perf branch March 31, 2026 18:36
@Will-ShaoHua
Will-ShaoHua restored the perf branch April 1, 2026 10:24
Will-ShaoHua added a commit that referenced this pull request Apr 2, 2026
Patch #743 
## Problem

The VS Code extension host forwards webview messages to the language
server using `sendNotification` for unhandled `aws/chat/*` methods (via
the `default` case in `messages.ts`). However, `onFilterContextCommands`
is registered as a **request** handler (`lspConnection.onRequest`).
Since request handlers do not fire for notifications, the server-side
context command filtering never executes.

This means in large repos (80k+ files), the `@` context picker can only
search the capped initial set of items pushed via `sendContextCommands`
(1000 items). Files beyond the cap are invisible to the user's search.

## Solution

Register both a **request** handler and a **notification** handler for
`filterContextCommands` in `base-runtime.ts` and `baseChat.ts`. The
request handler preserves compatibility with IDE hosts that use
`sendRequest`. The notification handler covers VS Code's
`sendNotification` path — it invokes the same filtering logic and pushes
results back to the client via `sendContextCommands`.

## Flow

```
User types in @ picker
  -> mynah-ui dispatches CONTEXT_COMMAND_FILTER (after 200ms debounce)
  -> chat-client sends postMessage to extension host
  -> extension host default case: sendNotification('aws/chat/filterContextCommands', params)
  -> [NEW] server notification handler fires
  -> server scores/sorts ALL cached items (e.g. 212k in linux kernel)
  -> server pushes top 1000 results via sendContextCommands notification
  -> client store updates -> picker refreshes with full search results
```

## e2e
see Amazon-Q-Developer/language-servers#2682
Will-ShaoHua pushed a commit that referenced this pull request Apr 3, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>chat-client-ui-types: 0.1.70</summary>

##
[0.1.70](chat-client-ui-types/v0.1.69...chat-client-ui-types/v0.1.70)
(2026-04-02)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @aws/language-server-runtimes-types bumped from ^0.1.63 to ^0.1.64
</details>

<details><summary>language-server-runtimes: 0.3.16</summary>

##
[0.3.16](language-server-runtimes/v0.3.15...language-server-runtimes/v0.3.16)
(2026-04-02)


### Features

* delegate lsp to handle context command filtering
([#743](#743))
([8836c33](8836c33))
* delegate lsp to handle context command filtering
([#745](#745))
([2c7174a](2c7174a))


### Bug Fixes

* bump node-forge to ^1.4.0 to resolve CVEs
([#746](#746))
([c1cd1a4](c1cd1a4))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @aws/language-server-runtimes-types bumped from ^0.1.63 to ^0.1.64
</details>

<details><summary>language-server-runtimes-types: 0.1.64</summary>

##
[0.1.64](language-server-runtimes-types/v0.1.63...language-server-runtimes-types/v0.1.64)
(2026-04-02)


### Features

* delegate lsp to handle context command filtering
([#743](#743))
([8836c33](8836c33))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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