Skip to content

Commit 0266d98

Browse files
authored
Merge branch 'feature/falcon' into autoMerge/feature/falcon
2 parents 91a54b0 + fe62f35 commit 0266d98

File tree

25 files changed

+1023
-27
lines changed

25 files changed

+1023
-27
lines changed

package-lock.json

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@
510510
"@aws-sdk/property-provider": "<3.696.0",
511511
"@aws-sdk/smithy-client": "<3.696.0",
512512
"@aws-sdk/util-arn-parser": "<3.696.0",
513-
"@aws/mynah-ui": "^4.22.1",
513+
"@aws/mynah-ui": "^4.23.0-beta.7",
514514
"@gerhobbelt/gitignore-parser": "^0.2.0-9",
515515
"@iarna/toml": "^2.2.5",
516516
"@smithy/middleware-retry": "^3.0.0",

packages/core/src/amazonq/lsp/lspClient.ts

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,18 @@ import {
2929
QueryRepomapIndexRequestType,
3030
GetRepomapIndexJSONRequestType,
3131
Usage,
32+
GetContextCommandItemsRequestType,
33+
ContextCommandItem,
34+
GetIndexSequenceNumberRequestType,
35+
GetContextCommandPromptRequestType,
36+
AdditionalContextPrompt,
3237
} from './types'
3338
import { Writable } from 'stream'
3439
import { CodeWhispererSettings } from '../../codewhisperer/util/codewhispererSettings'
3540
import { fs } from '../../shared/fs/fs'
3641
import { getLogger } from '../../shared/logger/logger'
3742
import globals from '../../shared/extensionGlobals'
43+
import { waitUntil } from '../../shared/utilities/timeoutUtils'
3844

3945
const localize = nls.loadMessageBundle()
4046

@@ -168,6 +174,66 @@ export class LspClient {
168174
throw e
169175
}
170176
}
177+
178+
async getContextCommandItems(): Promise<ContextCommandItem[]> {
179+
try {
180+
const workspaceFolders = vscode.workspace.workspaceFolders || []
181+
const request = JSON.stringify({
182+
workspaceFolders: workspaceFolders.map((it) => it.uri.fsPath),
183+
})
184+
const resp: any = await this.client?.sendRequest(
185+
GetContextCommandItemsRequestType,
186+
await this.encrypt(request)
187+
)
188+
return resp
189+
} catch (e) {
190+
getLogger().error(`LspClient: getContextCommandItems error: ${e}`)
191+
throw e
192+
}
193+
}
194+
195+
async getContextCommandPrompt(contextCommandItems: ContextCommandItem[]): Promise<AdditionalContextPrompt[]> {
196+
try {
197+
const request = JSON.stringify({
198+
contextCommands: contextCommandItems,
199+
})
200+
const resp: any = await this.client?.sendRequest(
201+
GetContextCommandPromptRequestType,
202+
await this.encrypt(request)
203+
)
204+
return resp
205+
} catch (e) {
206+
getLogger().error(`LspClient: getContextCommandPrompt error: ${e}`)
207+
throw e
208+
}
209+
}
210+
211+
async getIndexSequenceNumber(): Promise<number> {
212+
try {
213+
const request = JSON.stringify({})
214+
const resp: any = await this.client?.sendRequest(
215+
GetIndexSequenceNumberRequestType,
216+
await this.encrypt(request)
217+
)
218+
return resp
219+
} catch (e) {
220+
getLogger().error(`LspClient: getIndexSequenceNumber error: ${e}`)
221+
throw e
222+
}
223+
}
224+
225+
async waitUntilReady() {
226+
return waitUntil(
227+
async () => {
228+
if (this.client === undefined) {
229+
return false
230+
}
231+
await this.client.onReady()
232+
return true
233+
},
234+
{ interval: 500, timeout: 60_000 * 3, truthy: true }
235+
)
236+
}
171237
}
172238
/**
173239
* Activates the language server, this will start LSP server running over IPC protocol.
@@ -261,17 +327,41 @@ export async function activate(extensionContext: ExtensionContext) {
261327
void LspClient.instance.updateIndex([savedDocument.fsPath], 'update')
262328
}
263329
}),
264-
vscode.workspace.onDidCreateFiles((e) => {
265-
void LspClient.instance.updateIndex(
330+
vscode.workspace.onDidCreateFiles(async (e) => {
331+
const indexSeqNum = await LspClient.instance.getIndexSequenceNumber()
332+
await LspClient.instance.updateIndex(
266333
e.files.map((f) => f.fsPath),
267334
'add'
268335
)
336+
await waitUntil(
337+
async () => {
338+
const newIndexSeqNum = await LspClient.instance.getIndexSequenceNumber()
339+
if (newIndexSeqNum > indexSeqNum) {
340+
await vscode.commands.executeCommand(`aws.amazonq.updateContextCommandItems`)
341+
return true
342+
}
343+
return false
344+
},
345+
{ interval: 500, timeout: 10_000, truthy: true }
346+
)
269347
}),
270-
vscode.workspace.onDidDeleteFiles((e) => {
271-
void LspClient.instance.updateIndex(
348+
vscode.workspace.onDidDeleteFiles(async (e) => {
349+
const indexSeqNum = await LspClient.instance.getIndexSequenceNumber()
350+
await LspClient.instance.updateIndex(
272351
e.files.map((f) => f.fsPath),
273352
'remove'
274353
)
354+
await waitUntil(
355+
async () => {
356+
const newIndexSeqNum = await LspClient.instance.getIndexSequenceNumber()
357+
if (newIndexSeqNum > indexSeqNum) {
358+
await vscode.commands.executeCommand(`aws.amazonq.updateContextCommandItems`)
359+
return true
360+
}
361+
return false
362+
},
363+
{ interval: 500, timeout: 10_000, truthy: true }
364+
)
275365
})
276366
)
277367

packages/core/src/amazonq/lsp/lspController.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import fetch from 'node-fetch'
1313
import request from '../../shared/request'
1414
import { LspClient } from './lspClient'
1515
import AdmZip from 'adm-zip'
16-
import { RelevantTextDocument } from '@amzn/codewhisperer-streaming'
1716
import { makeTemporaryToolkitFolder, tryRemoveFolder } from '../../shared/filesystemUtilities'
1817
import { activate as activateLsp } from './lspClient'
1918
import { telemetry } from '../../shared/telemetry/telemetry'
@@ -24,13 +23,16 @@ import { ToolkitError } from '../../shared/errors'
2423
import { isWeb } from '../../shared/extensionGlobals'
2524
import { getUserAgent } from '../../shared/telemetry/util'
2625
import { isAmazonInternalOs } from '../../shared/vscode/env'
26+
import { RelevantTextDocumentAddition } from '../../codewhispererChat/controllers/chat/model'
2727

2828
export interface Chunk {
2929
readonly filePath: string
3030
readonly content: string
3131
readonly context?: string
3232
readonly relativePath?: string
3333
readonly programmingLanguage?: string
34+
readonly startLine?: number
35+
readonly endLine?: number
3436
}
3537

3638
export interface Content {
@@ -58,9 +60,9 @@ export interface Manifest {
5860
targets: Target[]
5961
}[]
6062
}
61-
const manifestUrl = 'https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json'
63+
const manifestUrl = 'https://ducvaeoffl85c.cloudfront.net/manifest-0.1.40.json'
6264
// this LSP client in Q extension is only going to work with these LSP server versions
63-
const supportedLspServerVersions = ['0.1.35']
65+
const supportedLspServerVersions = ['0.1.40']
6466

6567
const nodeBinName = process.platform === 'win32' ? 'node.exe' : 'node'
6668

@@ -279,9 +281,9 @@ export class LspController {
279281
}
280282
}
281283

282-
async query(s: string): Promise<RelevantTextDocument[]> {
284+
async query(s: string): Promise<RelevantTextDocumentAddition[]> {
283285
const chunks: Chunk[] | undefined = await LspClient.instance.queryVectorIndex(s)
284-
const resp: RelevantTextDocument[] = []
286+
const resp: RelevantTextDocumentAddition[] = []
285287
if (chunks) {
286288
for (const chunk of chunks) {
287289
const text = chunk.context ? chunk.context : chunk.content
@@ -292,11 +294,15 @@ export class LspController {
292294
programmingLanguage: {
293295
languageName: chunk.programmingLanguage,
294296
},
297+
startLine: chunk.startLine ?? -1,
298+
endLine: chunk.endLine ?? -1,
295299
})
296300
} else {
297301
resp.push({
298302
text: text,
299303
relativeFilePath: chunk.relativePath ? chunk.relativePath : path.basename(chunk.filePath),
304+
startLine: chunk.startLine ?? -1,
305+
endLine: chunk.endLine ?? -1,
300306
})
301307
}
302308
}
@@ -393,6 +399,7 @@ export class LspController {
393399
try {
394400
await activateLsp(context)
395401
getLogger().info('LspController: LSP activated')
402+
await vscode.commands.executeCommand(`aws.amazonq.updateContextCommandItems`)
396403
void LspController.instance.buildIndex(buildIndexConfig)
397404
// log the LSP server CPU and Memory usage per 30 minutes.
398405
globals.clock.setInterval(

packages/core/src/amazonq/lsp/types.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,43 @@ export type GetRepomapIndexJSONRequest = string
7676
export const GetRepomapIndexJSONRequestType: RequestType<GetRepomapIndexJSONRequest, any, any> = new RequestType(
7777
'lsp/getRepomapIndexJSON'
7878
)
79+
80+
export type GetContextCommandItemsRequestPayload = { workspaceFolders: string[] }
81+
export type GetContextCommandItemsRequest = string
82+
export const GetContextCommandItemsRequestType: RequestType<GetContextCommandItemsRequest, any, any> = new RequestType(
83+
'lsp/getContextCommandItems'
84+
)
85+
86+
export type GetIndexSequenceNumberRequest = string
87+
export const GetIndexSequenceNumberRequestType: RequestType<GetRepomapIndexJSONRequest, any, any> = new RequestType(
88+
'lsp/getIndexSequenceNumber'
89+
)
90+
91+
export type ContextCommandItemType = 'file' | 'folder'
92+
93+
export interface ContextCommandItem {
94+
workspaceFolder: string
95+
type: ContextCommandItemType
96+
relativePath: string
97+
}
98+
99+
export type GetContextCommandPromptRequestPayload = {
100+
contextCommands: {
101+
workspaceFolder: string
102+
type: 'file' | 'folder'
103+
relativePath: string
104+
}[]
105+
}
106+
export type GetContextCommandPromptRequest = string
107+
export const GetContextCommandPromptRequestType: RequestType<GetContextCommandPromptRequest, any, any> =
108+
new RequestType('lsp/getContextCommandPrompt')
109+
110+
export interface AdditionalContextPrompt {
111+
content: string
112+
name: string
113+
description: string
114+
startLine: number
115+
endLine: number
116+
filePath: string
117+
relativePath: string
118+
}

packages/core/src/amazonq/webview/messages/messageDispatcher.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export function dispatchWebViewMessagesToApps(
3636
})
3737
performance.clearMarks(amazonqMark.uiReady)
3838
performance.clearMarks(amazonqMark.open)
39+
// let cwcController know the ui is ready
40+
webViewToAppsMessagePublishers.get('cwc')?.publish(msg)
3941
return
4042
}
4143
case 'start-chat-message-telemetry': {

packages/core/src/amazonq/webview/ui/apps/baseConnector.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import { ChatItem, ChatItemAction, ChatItemType, FeedbackPayload } from '@aws/mynah-ui'
6+
import { ChatItem, ChatItemAction, ChatItemType, FeedbackPayload, QuickActionCommand } from '@aws/mynah-ui'
77
import { ExtensionMessage } from '../commands'
88
import { CodeReference } from './amazonqCommonsConnector'
99
import { TabOpenType, TabsStorage, TabType } from '../storages/tabsStorage'
@@ -13,6 +13,7 @@ import { CWCChatItem } from '../connector'
1313
interface ChatPayload {
1414
chatMessage: string
1515
chatCommand?: string
16+
chatContext?: string[] | QuickActionCommand[]
1617
}
1718

1819
export interface BaseConnectorProps {
@@ -212,6 +213,7 @@ export abstract class BaseConnector {
212213
command: 'chat-prompt',
213214
chatMessage: payload.chatMessage,
214215
chatCommand: payload.chatCommand,
216+
chatContext: payload.chatContext,
215217
tabType: this.getTabType(),
216218
})
217219
})

0 commit comments

Comments
 (0)