Skip to content

Commit 8f9c157

Browse files
authored
feat(amazonq): Adding userIntent for insertAtCursor and copyToClipboard events for telemetry. (#4951)
* Adding Acceptance metrics for UTG
1 parent 6afc927 commit 8f9c157

File tree

5 files changed

+113
-43
lines changed

5 files changed

+113
-43
lines changed

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,14 @@ class ChatPromptHandler(private val telemetryHelper: TelemetryHelper) {
5858
.onStart {
5959
// The first thing we always send back is an AnswerStream message to indicate the beginning of a streaming answer
6060
val response =
61-
ChatMessage(tabId = tabId, triggerId = triggerId, messageId = requestId, messageType = ChatMessageType.AnswerStream, message = "")
61+
ChatMessage(
62+
tabId = tabId,
63+
triggerId = triggerId,
64+
messageId = requestId,
65+
messageType = ChatMessageType.AnswerStream,
66+
message = "",
67+
userIntent = data.userIntent,
68+
)
6269

6370
telemetryHelper.setResponseStreamStartTime(tabId)
6471
emit(response)
@@ -81,13 +88,20 @@ class ChatPromptHandler(private val telemetryHelper: TelemetryHelper) {
8188
messageType = ChatMessageType.AnswerPart,
8289
message = responseText.toString(),
8390
relatedSuggestions = relatedSuggestions,
91+
userIntent = data.userIntent,
8492
)
8593
emit(suggestionMessage)
8694
}
8795

8896
// Send the Answer message to indicate the end of the response stream
89-
val response =
90-
ChatMessage(tabId = tabId, triggerId = triggerId, messageId = requestId, messageType = ChatMessageType.Answer, followUps = followUps)
97+
val response = ChatMessage(
98+
tabId = tabId,
99+
triggerId = triggerId,
100+
messageId = requestId,
101+
messageType = ChatMessageType.Answer,
102+
followUps = followUps,
103+
userIntent = data.userIntent,
104+
)
91105

92106
telemetryHelper.setResponseStreamTotalTime(tabId)
93107
telemetryHelper.setResponseHasProjectContext(
@@ -119,11 +133,23 @@ class ChatPromptHandler(private val telemetryHelper: TelemetryHelper) {
119133
}
120134
}
121135
.collect { responseEvent ->
122-
processChatEvent(tabId, triggerId, responseEvent, shouldAddIndexInProgressMessage)?.let { emit(it) }
136+
processChatEvent(
137+
tabId,
138+
triggerId,
139+
data,
140+
responseEvent,
141+
shouldAddIndexInProgressMessage
142+
)?.let { emit(it) }
123143
}
124144
}
125145

126-
private fun processChatEvent(tabId: String, triggerId: String, event: ChatResponseEvent, shouldAddIndexInProgressMessage: Boolean): ChatMessage? {
146+
private fun processChatEvent(
147+
tabId: String,
148+
triggerId: String,
149+
data: ChatRequestData,
150+
event: ChatResponseEvent,
151+
shouldAddIndexInProgressMessage: Boolean,
152+
): ChatMessage? {
127153
requestId = event.requestId
128154
statusCode = event.statusCode
129155

@@ -190,6 +216,7 @@ class ChatPromptHandler(private val telemetryHelper: TelemetryHelper) {
190216
messageType = ChatMessageType.AnswerPart,
191217
message = message,
192218
codeReference = codeReferences,
219+
userIntent = data.userIntent,
193220
)
194221
} else {
195222
null

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/messages/CwcMessage.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ data class ChatMessage(
213213
val followUpsHeader: String? = null,
214214
val relatedSuggestions: List<Suggestion>? = null,
215215
val codeReference: List<CodeReference>? = null,
216+
val userIntent: UserIntent? = null,
216217
) : UiMessage(
217218
tabId = tabId,
218219
type = "chatMessage",

plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/cwChatConnector.ts

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

6-
import { ChatItem, ChatItemAction, ChatItemType, FeedbackPayload } from '@aws/mynah-ui-chat'
6+
import { ChatItemAction, ChatItemType, FeedbackPayload } from '@aws/mynah-ui-chat'
77
import { ExtensionMessage } from '../commands'
88
import { CodeReference } from './amazonqCommonsConnector'
99
import { TabOpenType, TabsStorage } from '../storages/tabsStorage'
1010
import { FollowUpGenerator } from '../followUps/generator'
11+
import { CWCChatItem } from "../connector";
1112

1213
interface ChatPayload {
1314
chatMessage: string
@@ -17,8 +18,8 @@ interface ChatPayload {
1718
export interface ConnectorProps {
1819
sendMessageToExtension: (message: ExtensionMessage) => void
1920
onMessageReceived?: (tabID: string, messageData: any, needToShowAPIDocsTab: boolean) => void
20-
onChatAnswerReceived?: (tabID: string, message: ChatItem) => void
21-
onCWCContextCommandMessage: (message: ChatItem, command?: string) => string | undefined
21+
onChatAnswerReceived?: (tabID: string, message: CWCChatItem) => void
22+
onCWCContextCommandMessage: (message: CWCChatItem, command?: string) => string | undefined
2223
onError: (tabID: string, message: string, title: string) => void
2324
onWarning: (tabID: string, message: string, title: string) => void
2425
onOpenSettingsMessage: (tabID: string) => void
@@ -98,7 +99,8 @@ export class Connector {
9899
codeReference?: CodeReference[],
99100
eventId?: string,
100101
codeBlockIndex?: number,
101-
totalCodeBlocks?: number
102+
totalCodeBlocks?: number,
103+
userIntent?: string,
102104
): void => {
103105
this.sendMessageToExtension({
104106
tabID: tabID,
@@ -111,6 +113,7 @@ export class Connector {
111113
eventId,
112114
codeBlockIndex,
113115
totalCodeBlocks,
116+
userIntent
114117
})
115118
}
116119

@@ -122,7 +125,8 @@ export class Connector {
122125
codeReference?: CodeReference[],
123126
eventId?: string,
124127
codeBlockIndex?: number,
125-
totalCodeBlocks?: number
128+
totalCodeBlocks?: number,
129+
userIntent?: string,
126130
): void => {
127131
this.sendMessageToExtension({
128132
tabID: tabID,
@@ -135,6 +139,7 @@ export class Connector {
135139
eventId,
136140
codeBlockIndex,
137141
totalCodeBlocks,
142+
userIntent
138143
})
139144
}
140145

@@ -258,13 +263,14 @@ export class Connector {
258263
}
259264
: undefined
260265

261-
const answer: ChatItem = {
266+
const answer: CWCChatItem = {
262267
type: messageData.messageType,
263268
messageId: messageData.messageId ?? messageData.triggerID,
264269
body: messageData.message,
265270
followUp: followUps,
266271
canBeVoted: true,
267272
codeReference: messageData.codeReference,
273+
userIntent: messageData.userIntent,
268274
}
269275

270276
// If it is not there we will not set it
@@ -291,12 +297,13 @@ export class Connector {
291297
return
292298
}
293299
if (messageData.messageType === ChatItemType.ANSWER) {
294-
const answer: ChatItem = {
300+
const answer: CWCChatItem = {
295301
type: messageData.messageType,
296302
body: undefined,
297303
relatedContent: undefined,
298304
messageId: messageData.messageId,
299305
codeReference: messageData.codeReference,
306+
userIntent: messageData.userIntent,
300307
followUp:
301308
messageData.followUps !== undefined && messageData.followUps.length > 0
302309
? {

plugins/amazonq/mynah-ui/src/mynah-ui/ui/connector.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ export interface ChatPayload {
3030
chatCommand?: string
3131
}
3232

33+
export interface CWCChatItem extends ChatItem {
34+
userIntent?: string
35+
}
36+
3337
export interface ConnectorProps {
3438
sendMessageToExtension: (message: ExtensionMessage) => void
3539
onMessageReceived?: (tabID: string, messageData: any, needToShowAPIDocsTab: boolean) => void
@@ -230,7 +234,8 @@ export class Connector {
230234
codeReference?: CodeReference[],
231235
eventId?: string,
232236
codeBlockIndex?: number,
233-
totalCodeBlocks?: number
237+
totalCodeBlocks?: number,
238+
userIntent?: string
234239
): void => {
235240
switch (this.tabsStorage.getTab(tabID)?.type) {
236241
case 'cwc':
@@ -242,7 +247,8 @@ export class Connector {
242247
codeReference,
243248
eventId,
244249
codeBlockIndex,
245-
totalCodeBlocks
250+
totalCodeBlocks,
251+
userIntent
246252
)
247253
break
248254
case 'featuredev':
@@ -259,7 +265,8 @@ export class Connector {
259265
codeReference?: CodeReference[],
260266
eventId?: string,
261267
codeBlockIndex?: number,
262-
totalCodeBlocks?: number
268+
totalCodeBlocks?: number,
269+
userIntent?: string
263270
): void => {
264271
switch (this.tabsStorage.getTab(tabID)?.type) {
265272
case 'cwc':
@@ -271,7 +278,8 @@ export class Connector {
271278
codeReference,
272279
eventId,
273280
codeBlockIndex,
274-
totalCodeBlocks
281+
totalCodeBlocks,
282+
userIntent
275283
)
276284
break
277285
case 'featuredev':

plugins/amazonq/mynah-ui/src/mynah-ui/ui/main.ts

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
import { Connector } from './connector'
6-
import { ChatItem, ChatItemType, MynahIcons, MynahUI, MynahUIDataModel, NotificationType } from '@aws/mynah-ui-chat'
5+
import { Connector, CWCChatItem } from './connector'
6+
import {ChatItem, ChatItemType, MynahIcons, MynahUI, MynahUIDataModel, NotificationType, ReferenceTrackerInformation} from '@aws/mynah-ui-chat'
77
import './styles/dark.scss'
88
import { TabsStorage, TabType } from './storages/tabsStorage'
99
import { WelcomeFollowupType } from './apps/amazonqCommonsConnector'
@@ -17,12 +17,15 @@ import { MessageController } from './messages/controller'
1717
import { getActions, getDetails } from './diffTree/actions'
1818
import { DiffTreeFileInfo } from './diffTree/types'
1919
import './styles.css'
20+
import {CodeSelectionType} from "@aws/mynah-ui-chat/dist/static";
2021

2122
export const createMynahUI = (ideApi: any, featureDevInitEnabled: boolean, codeTransformInitEnabled: boolean) => {
2223
// eslint-disable-next-line prefer-const
2324
let mynahUI: MynahUI
2425
// eslint-disable-next-line prefer-const
2526
let connector: Connector
27+
const messageUserIntentMap = new Map<string, string>()
28+
2629
const tabsStorage = new TabsStorage({
2730
onTabTimeout: tabID => {
2831
mynahUI.addChatItem(tabID, {
@@ -239,7 +242,7 @@ export const createMynahUI = (ideApi: any, featureDevInitEnabled: boolean, codeT
239242
sendMessageToExtension: message => {
240243
ideApi.postMessage(message)
241244
},
242-
onChatAnswerReceived: (tabID: string, item: ChatItem) => {
245+
onChatAnswerReceived: (tabID: string, item: CWCChatItem) => {
243246
if (item.type === ChatItemType.ANSWER_PART || item.type === ChatItemType.CODE_RESULT) {
244247
mynahUI.updateLastChatAnswer(tabID, {
245248
...(item.messageId !== undefined ? { messageId: item.messageId } : {}),
@@ -251,6 +254,9 @@ export const createMynahUI = (ideApi: any, featureDevInitEnabled: boolean, codeT
251254
? { type: ChatItemType.CODE_RESULT, fileList: item.fileList }
252255
: {}),
253256
})
257+
if (item.messageId !== undefined && item.userIntent !== undefined) {
258+
messageUserIntentMap.set(item.messageId, item.userIntent)
259+
}
254260
return
255261
}
256262

@@ -437,31 +443,52 @@ export const createMynahUI = (ideApi: any, featureDevInitEnabled: boolean, codeT
437443
content: 'Thanks for your feedback.',
438444
})
439445
},
440-
onCodeInsertToCursorPosition: connector.onCodeInsertToCursorPosition,
441-
onCopyCodeToClipboard: (
442-
tabId,
443-
messageId,
444-
code,
445-
type,
446-
referenceTrackerInfo,
447-
eventId,
448-
codeBlockIndex,
449-
totalCodeBlocks
446+
onCodeBlockActionClicked: (
447+
tabId: string,
448+
messageId: string,
449+
actionId: string,
450+
data?: string,
451+
code?: string,
452+
type?: CodeSelectionType,
453+
referenceTrackerInformation?: ReferenceTrackerInformation[],
454+
eventId?: string,
455+
codeBlockIndex?: number,
456+
totalCodeBlocks?: number
450457
) => {
451-
connector.onCopyCodeToClipboard(
452-
tabId,
453-
messageId,
454-
code,
455-
type,
456-
referenceTrackerInfo,
457-
eventId,
458-
codeBlockIndex,
459-
totalCodeBlocks
460-
)
461-
mynahUI.notify({
462-
type: NotificationType.SUCCESS,
463-
content: 'Selected code is copied to clipboard',
464-
})
458+
switch (actionId) {
459+
case 'insert-to-cursor':
460+
connector.onCodeInsertToCursorPosition(
461+
tabId,
462+
messageId,
463+
code,
464+
type,
465+
referenceTrackerInformation,
466+
eventId,
467+
codeBlockIndex,
468+
totalCodeBlocks,
469+
messageUserIntentMap.get(messageId) ?? undefined
470+
)
471+
break
472+
case 'copy':
473+
connector.onCopyCodeToClipboard(
474+
tabId,
475+
messageId,
476+
code,
477+
type,
478+
referenceTrackerInformation,
479+
eventId,
480+
codeBlockIndex,
481+
totalCodeBlocks,
482+
messageUserIntentMap.get(messageId) ?? undefined
483+
)
484+
mynahUI.notify({
485+
type: NotificationType.SUCCESS,
486+
content: 'Selected code is copied to clipboard',
487+
})
488+
break
489+
default:
490+
break
491+
}
465492
},
466493
onChatItemEngagement: connector.triggerSuggestionEngagement,
467494
onSourceLinkClick: (tabId, messageId, link, mouseEvent) => {

0 commit comments

Comments
 (0)