Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
439 changes: 398 additions & 41 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Feature",
"description": "Add model selection feature"
}
9 changes: 7 additions & 2 deletions packages/amazonq/src/lsp/chat/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { window } from 'vscode'
import { LanguageClient } from 'vscode-languageclient'
import { AmazonQChatViewProvider } from './webviewProvider'
import { focusAmazonQPanel, registerCommands } from './commands'
import { registerLanguageServerEventListener, registerMessageListeners } from './messages'
import {
registerActiveEditorChangeListener,
registerLanguageServerEventListener,
registerMessageListeners,
} from './messages'
import { Commands, getLogger, globals, undefinedIfEmpty } from 'aws-core-vscode/shared'
import { activate as registerLegacyChatListeners } from '../../app/chat/activation'
import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq'
Expand All @@ -17,7 +21,7 @@ import { pushConfigUpdate } from '../config'
export async function activate(languageClient: LanguageClient, encryptionKey: Buffer, mynahUIPath: string) {
const disposables = globals.context.subscriptions

const provider = new AmazonQChatViewProvider(mynahUIPath)
const provider = new AmazonQChatViewProvider(mynahUIPath, languageClient)

disposables.push(
window.registerWebviewViewProvider(AmazonQChatViewProvider.viewType, provider, {
Expand All @@ -33,6 +37,7 @@ export async function activate(languageClient: LanguageClient, encryptionKey: Bu
**/
registerCommands(provider)
registerLanguageServerEventListener(languageClient, provider)
registerActiveEditorChangeListener(languageClient)

provider.onDidResolveWebview(() => {
const disposable = DefaultAmazonQAppInitContext.instance.getAppsToWebViewMessageListener().onMessage((msg) => {
Expand Down
45 changes: 44 additions & 1 deletion packages/amazonq/src/lsp/chat/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,18 @@ import {
ChatUpdateParams,
chatOptionsUpdateType,
ChatOptionsUpdateParams,
listRulesRequestType,
ruleClickRequestType,
pinnedContextNotificationType,
activeEditorChangedNotificationType,
} from '@aws/language-server-runtimes/protocol'
import { v4 as uuidv4 } from 'uuid'
import * as vscode from 'vscode'
import { Disposable, LanguageClient, Position, TextDocumentIdentifier } from 'vscode-languageclient'
import * as jose from 'jose'
import { AmazonQChatViewProvider } from './webviewProvider'
import { AuthUtil, ReferenceLogViewProvider } from 'aws-core-vscode/codewhisperer'
import { amazonQDiffScheme, AmazonQPromptSettings, messages, openUrl } from 'aws-core-vscode/shared'
import { amazonQDiffScheme, AmazonQPromptSettings, messages, openUrl, isTextEditor } from 'aws-core-vscode/shared'
import {
DefaultAmazonQAppInitContext,
messageDispatcher,
Expand All @@ -74,6 +78,29 @@ import { telemetry, TelemetryBase } from 'aws-core-vscode/telemetry'
import { isValidResponseError } from './error'
import { focusAmazonQPanel } from './commands'

export function registerActiveEditorChangeListener(languageClient: LanguageClient) {
let debounceTimer: NodeJS.Timeout | undefined
vscode.window.onDidChangeActiveTextEditor((editor) => {
if (debounceTimer) {
clearTimeout(debounceTimer)
}
debounceTimer = setTimeout(() => {
let textDocument = undefined
let cursorState = undefined
if (editor) {
textDocument = {
uri: editor.document.uri.toString(),
}
cursorState = getCursorState(editor.selections)
}
languageClient.sendNotification(activeEditorChangedNotificationType.method, {
textDocument,
cursorState,
})
}, 100)
})
}

export function registerLanguageServerEventListener(languageClient: LanguageClient, provider: AmazonQChatViewProvider) {
languageClient.info(
'Language client received initializeResult from server:',
Expand Down Expand Up @@ -316,6 +343,8 @@ export function registerMessageListeners(
)
break
}
case listRulesRequestType.method:
case ruleClickRequestType.method:
case listConversationsRequestType.method:
case conversationClickRequestType.method:
case listMcpServersRequestType.method:
Expand Down Expand Up @@ -471,6 +500,20 @@ export function registerMessageListeners(
params: params,
})
})
languageClient.onNotification(
pinnedContextNotificationType.method,
(params: ContextCommandParams & { tabId: string; textDocument?: TextDocumentIdentifier }) => {
const editor = vscode.window.activeTextEditor
let textDocument = undefined
if (editor && isTextEditor(editor)) {
textDocument = { uri: vscode.workspace.asRelativePath(editor.document.uri) }
}
void provider.webview?.postMessage({
command: pinnedContextNotificationType.method,
params: { ...params, textDocument },
})
}
)

languageClient.onNotification(openFileDiffNotificationType.method, async (params: OpenFileDiffParams) => {
const ecc = new EditorContentController()
Expand Down
12 changes: 9 additions & 3 deletions packages/amazonq/src/lsp/chat/webviewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
import { AuthUtil, RegionProfile } from 'aws-core-vscode/codewhisperer'
import { featureConfig } from 'aws-core-vscode/amazonq'
import { getAmazonQLspConfig } from '../config'
import { LanguageClient } from 'vscode-languageclient'

export class AmazonQChatViewProvider implements WebviewViewProvider {
public static readonly viewType = 'aws.amazonq.AmazonQChatView'
Expand All @@ -36,7 +37,10 @@ export class AmazonQChatViewProvider implements WebviewViewProvider {
connectorAdapterPath?: string
uiPath?: string

constructor(private readonly mynahUIPath: string) {}
constructor(
private readonly mynahUIPath: string,
private readonly languageClient: LanguageClient
) {}

public async resolveWebviewView(
webviewView: WebviewView,
Expand Down Expand Up @@ -95,6 +99,8 @@ export class AmazonQChatViewProvider implements WebviewViewProvider {
const pairProgrammingAcknowledged =
!AmazonQPromptSettings.instance.isPromptEnabled('amazonQChatPairProgramming')
const welcomeCount = globals.globalState.tryGet('aws.amazonq.welcomeChatShowCount', Number, 0)
const modelSelectionEnabled =
this.languageClient.initializeResult?.awsServerCapabilities?.chatOptions?.modelSelection ?? false

// only show profile card when the two conditions
// 1. profile count >= 2
Expand Down Expand Up @@ -143,14 +149,14 @@ export class AmazonQChatViewProvider implements WebviewViewProvider {
const vscodeApi = acquireVsCodeApi()
const hybridChatConnector = new HybridChatAdapter(${(await AuthUtil.instance.getChatAuthState()).amazonQ === 'connected'},${featureConfigData},${welcomeCount},${disclaimerAcknowledged},${regionProfileString},${disabledCommands},${isSMUS},${isSM},vscodeApi.postMessage)
const commands = [hybridChatConnector.initialQuickActions[0]]
qChat = amazonQChat.createChat(vscodeApi, {disclaimerAcknowledged: ${disclaimerAcknowledged}, pairProgrammingAcknowledged: ${pairProgrammingAcknowledged}, agenticMode: true, quickActionCommands: commands}, hybridChatConnector, ${JSON.stringify(featureConfigData)});
qChat = amazonQChat.createChat(vscodeApi, {disclaimerAcknowledged: ${disclaimerAcknowledged}, pairProgrammingAcknowledged: ${pairProgrammingAcknowledged}, agenticMode: true, quickActionCommands: commands, modelSelectionEnabled: ${modelSelectionEnabled}}, hybridChatConnector, ${JSON.stringify(featureConfigData)});
}
window.addEventListener('message', (event) => {
/**
* special handler that "simulates" reloading the webview when a profile changes.
* required because chat-client relies on initializedResult from the lsp that
* are only sent once
*
*
* References:
* closing tabs: https://github.com/aws/mynah-ui/blob/de736b52f369ba885cd19f33ac86c6f57b4a3134/docs/USAGE.md#removing-a-tab-programmatically-
* opening tabs: https://github.com/aws/aws-toolkit-vscode/blob/c22efa03e73b241564c8051c35761eb8620edb83/packages/amazonq/test/e2e/amazonq/framework/framework.ts#L98
Expand Down
1 change: 1 addition & 0 deletions packages/amazonq/src/lsp/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export async function startLanguageServer(
awsClientCapabilities: {
q: {
developerProfiles: true,
pinnedContextEnabled: true,
mcp: true,
},
window: {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@
"@aws-sdk/types": "^3.13.1",
"@aws/chat-client": "^0.1.4",
"@aws/chat-client-ui-types": "^0.1.24",
"@aws/language-server-runtimes": "^0.2.81",
"@aws/language-server-runtimes-types": "^0.1.28",
"@aws/language-server-runtimes": "^0.2.97",
"@aws/language-server-runtimes-types": "^0.1.39",
"@cspotcode/source-map-support": "^0.8.1",
"@sinonjs/fake-timers": "^10.0.2",
"@types/adm-zip": "^0.4.34",
Expand Down Expand Up @@ -526,7 +526,7 @@
"@aws-sdk/s3-request-presigner": "<3.731.0",
"@aws-sdk/smithy-client": "<3.731.0",
"@aws-sdk/util-arn-parser": "<3.731.0",
"@aws/mynah-ui": "^4.34.1",
"@aws/mynah-ui": "^4.35.4",
"@gerhobbelt/gitignore-parser": "^0.2.0-9",
"@iarna/toml": "^2.2.5",
"@smithy/fetch-http-handler": "^5.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ export class QuickActionHandler {
cancelButtonWhenLoading: false,
})
} else {
this.mynahUI.updateStore(affectedTabId, { promptInputOptions: [] })
this.mynahUI.updateStore(affectedTabId, { promptInputOptions: [], promptTopBarTitle: '' })
}

if (affectedTabId && this.isHybridChatEnabled) {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export * from './vscode/commands2'
export * from './utilities/pathUtils'
export * from './utilities/zipStream'
export * from './errors'
export { isTextEditor } from './utilities/editorUtilities'
export * as messages from './utilities/messages'
export * as errors from './errors'
export * as funcUtil from './utilities/functionUtils'
Expand Down
Loading