Skip to content

Commit 89903fe

Browse files
authored
fix(amazonq): chatOptions are missing in q chat (#7520)
## Problem - Missing `chatOptions` like mcp icon, history icon, export icon in tab bar and quickActions like `/clear` and `/help` in the input menu. ![image](https://github.com/user-attachments/assets/386fd680-991e-4f61-821c-276d5e66df2b) #### Root Cause 1: - The `CHAT_OPTIONS` command is sometimes not properly received by the handleInboundMessage function in the chat client. - The root issue was a race condition in the communication between the VSCode extension and the webview component. When the `onDidResolveWebview` event fired, the code was immediately trying to send a message to the webview, but in some cases, the webview wasn't fully ready to receive messages yet, causing the message to be lost. #### Root Cause 2: - If user opens a large repository(example: [JetBrains](https://github.com/aws/aws-toolkit-jetbrains)) in any IDE(VSC or JB or VS or Ecllipse), IDE takes some time to do indexing. - This delay of indexing is stopping the webview to initialize and if the webview is delayed, the `chatOptions` like quickActions(`/help` or `/clear`) and tab bar icons are not sent because of webview delay. ## Ideal case: - VSC Extension at `messages.ts`, `chatOptions` are sent to the [webview using webview.postMessage() with the command CHAT_OPTIONS](https://github.com/aws/language-servers/blob/0cac52c3d037da8fc4403f030738256b07195e76/client/vscode/src/chatActivation.ts#L340-L348) and this is handled by the `handleInboundMessage` in `LS/chat.ts` file. ## Solution: 1. Listen to dedicated `aws/chat/ready` event, which ensures we only send messages when the UI is fully initialized and ready to process them. 2. The chat options are stored when initialized, and then sent when the `aws/chat/ready` event is received from the UI. 3. Added explicit try/catch around the message sending process with proper error logging. 4. Added clearer log messages to track the UI ready event and message sending process, which will make debugging easier if issues arise in the future. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 76effe0 commit 89903fe

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

packages/amazonq/src/lsp/chat/messages.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
LINK_CLICK_NOTIFICATION_METHOD,
4949
LinkClickParams,
5050
INFO_LINK_CLICK_NOTIFICATION_METHOD,
51+
READY_NOTIFICATION_METHOD,
5152
buttonClickRequestType,
5253
ButtonClickResult,
5354
CancellationTokenSource,
@@ -115,19 +116,12 @@ export function registerLanguageServerEventListener(languageClient: LanguageClie
115116
chatOptions.quickActions.quickActionsCommandGroups[0].groupName = 'Quick Actions'
116117
}
117118

118-
provider.onDidResolveWebview(() => {
119-
void provider.webview?.postMessage({
120-
command: CHAT_OPTIONS,
121-
params: chatOptions,
122-
})
123-
})
124-
125119
// This passes through metric data from LSP events to Toolkit telemetry with all fields from the LSP server
126120
languageClient.onTelemetry((e) => {
127121
const telemetryName: string = e.name
128122

129123
if (telemetryName in telemetry) {
130-
languageClient.info(`[Telemetry] Emitting ${telemetryName} telemetry: ${JSON.stringify(e.data)}`)
124+
languageClient.info(`[VSCode Telemetry] Emitting ${telemetryName} telemetry: ${JSON.stringify(e.data)}`)
131125
telemetry[telemetryName as keyof TelemetryBase].emit(e.data)
132126
}
133127
})
@@ -139,6 +133,10 @@ export function registerMessageListeners(
139133
encryptionKey: Buffer
140134
) {
141135
const chatStreamTokens = new Map<string, CancellationTokenSource>() // tab id -> token
136+
137+
// Keep track of pending chat options to send when webview UI is ready
138+
const pendingChatOptions = languageClient.initializeResult?.awsServerCapabilities?.chatOptions
139+
142140
provider.webview?.onDidReceiveMessage(async (message) => {
143141
languageClient.info(`[VSCode Client] Received ${JSON.stringify(message)} from chat`)
144142

@@ -152,7 +150,32 @@ export function registerMessageListeners(
152150
}
153151

154152
const webview = provider.webview
153+
155154
switch (message.command) {
155+
// Handle "aws/chat/ready" event
156+
case READY_NOTIFICATION_METHOD:
157+
languageClient.info(`[VSCode Client] "aws/chat/ready" event is received, sending chat options`)
158+
if (webview && pendingChatOptions) {
159+
try {
160+
await webview.postMessage({
161+
command: CHAT_OPTIONS,
162+
params: pendingChatOptions,
163+
})
164+
165+
// Display a more readable representation of quick actions
166+
const quickActionCommands =
167+
pendingChatOptions?.quickActions?.quickActionsCommandGroups?.[0]?.commands || []
168+
const quickActionsDisplay = quickActionCommands.map((cmd: any) => cmd.command).join(', ')
169+
languageClient.info(
170+
`[VSCode Client] Chat options flags: mcpServers=${pendingChatOptions?.mcpServers}, history=${pendingChatOptions?.history}, export=${pendingChatOptions?.export}, quickActions=[${quickActionsDisplay}]`
171+
)
172+
} catch (err) {
173+
languageClient.error(
174+
`[VSCode Client] Failed to send CHAT_OPTIONS after "aws/chat/ready" event: ${(err as Error).message}`
175+
)
176+
}
177+
}
178+
break
156179
case COPY_TO_CLIPBOARD:
157180
languageClient.info('[VSCode Client] Copy to clipboard event received')
158181
try {

0 commit comments

Comments
 (0)