Skip to content

Commit 5aace55

Browse files
committed
Grouping read tool messages together.
1 parent e9cfe3a commit 5aace55

File tree

10 files changed

+245
-92
lines changed

10 files changed

+245
-92
lines changed

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,32 @@ export class Connector extends BaseConnector {
178178
}
179179
}
180180

181+
private processToolMessage = async (messageData: any): Promise<void> => {
182+
if (this.onChatAnswerUpdated === undefined) {
183+
return
184+
}
185+
const answer: CWCChatItem = {
186+
type: messageData.messageType,
187+
messageId: messageData.messageID ?? messageData.triggerID,
188+
body: messageData.message,
189+
followUp: messageData.followUps,
190+
canBeVoted: messageData.canBeVoted ?? false,
191+
codeReference: messageData.codeReference,
192+
userIntent: messageData.contextList,
193+
codeBlockLanguage: messageData.codeBlockLanguage,
194+
contextList: messageData.contextList,
195+
title: messageData.title,
196+
buttons: messageData.buttons,
197+
fileList: messageData.fileList,
198+
header: messageData.header ?? undefined,
199+
padding: messageData.padding ?? undefined,
200+
fullWidth: messageData.fullWidth ?? undefined,
201+
codeBlockActions: messageData.codeBlockActions ?? undefined,
202+
}
203+
this.onChatAnswerUpdated(messageData.tabID, answer)
204+
return
205+
}
206+
181207
private storeChatItem(tabId: string, messageId: string, item: ChatItem): void {
182208
if (!this.chatItems.has(tabId)) {
183209
this.chatItems.set(tabId, new Map())
@@ -237,6 +263,11 @@ export class Connector extends BaseConnector {
237263
return
238264
}
239265

266+
if (messageData.type === 'toolMessage') {
267+
await this.processToolMessage(messageData)
268+
return
269+
}
270+
240271
if (messageData.type === 'editorContextCommandMessage') {
241272
await this.processEditorContextCommandMessage(messageData)
242273
return

packages/core/src/amazonq/webview/ui/connector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export interface ConnectorProps {
7777
sendMessageToExtension: (message: ExtensionMessage) => void
7878
onMessageReceived?: (tabID: string, messageData: any, needToShowAPIDocsTab: boolean) => void
7979
onRunTestMessageReceived?: (tabID: string, showRunTestMessage: boolean) => void
80-
onChatAnswerUpdated?: (tabID: string, message: ChatItem) => void
80+
onChatAnswerUpdated?: (tabID: string, message: CWCChatItem) => void
8181
onChatAnswerReceived?: (tabID: string, message: ChatItem, messageData: any) => void
8282
onWelcomeFollowUpClicked: (tabID: string, welcomeFollowUpType: WelcomeFollowupType) => void
8383
onAsyncEventProgress: (tabID: string, inProgress: boolean, message: string | undefined) => void

packages/core/src/amazonq/webview/ui/main.ts

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,41 @@ export const createMynahUI = (
9898
welcomeCount += 1
9999
}
100100

101+
/**
102+
* Creates a file list header from context list
103+
* @param contextList List of file contexts
104+
* @param title Title for the root folder
105+
* @returns Header object with file list
106+
*/
107+
const createFileListHeader = (contextList: any[], title?: string) => {
108+
return {
109+
fileList: {
110+
fileTreeTitle: '',
111+
filePaths: contextList.map((file) => file.relativeFilePath),
112+
rootFolderTitle: title,
113+
flatList: true,
114+
collapsed: true,
115+
hideFileCount: true,
116+
details: Object.fromEntries(
117+
contextList.map((file) => [
118+
file.relativeFilePath,
119+
{
120+
label: file.lineRanges
121+
.map((range: { first: number; second: number }) =>
122+
range.first === -1 || range.second === -1
123+
? ''
124+
: `line ${range.first} - ${range.second}`
125+
)
126+
.join(', '),
127+
description: file.relativeFilePath,
128+
clickable: true,
129+
},
130+
])
131+
),
132+
},
133+
}
134+
}
135+
101136
// Adding the first tab as CWC tab
102137
tabsStorage.addTab({
103138
id: 'tab-1',
@@ -342,8 +377,11 @@ export const createMynahUI = (
342377
sendMessageToExtension: (message) => {
343378
ideApi.postMessage(message)
344379
},
345-
onChatAnswerUpdated: (tabID: string, item: ChatItem) => {
380+
onChatAnswerUpdated: (tabID: string, item: CWCChatItem) => {
346381
if (item.messageId !== undefined) {
382+
if (item.contextList !== undefined && item.contextList.length > 0) {
383+
item.header = createFileListHeader(item.contextList, item.title)
384+
}
347385
mynahUI.updateChatAnswerWithMessageId(tabID, item.messageId, {
348386
...(item.body !== undefined ? { body: item.body } : {}),
349387
...(item.buttons !== undefined ? { buttons: item.buttons } : {}),
@@ -405,32 +443,7 @@ export const createMynahUI = (
405443
}
406444

407445
if (item.contextList !== undefined && item.contextList.length > 0) {
408-
item.header = {
409-
fileList: {
410-
fileTreeTitle: '',
411-
filePaths: item.contextList.map((file) => file.relativeFilePath),
412-
rootFolderTitle: item.title,
413-
flatList: true,
414-
collapsed: true,
415-
hideFileCount: true,
416-
details: Object.fromEntries(
417-
item.contextList.map((file) => [
418-
file.relativeFilePath,
419-
{
420-
label: file.lineRanges
421-
.map((range) =>
422-
range.first === -1 || range.second === -1
423-
? ''
424-
: `line ${range.first} - ${range.second}`
425-
)
426-
.join(', '),
427-
description: file.relativeFilePath,
428-
clickable: true,
429-
},
430-
])
431-
),
432-
},
433-
}
446+
item.header = createFileListHeader(item.contextList, item.title)
434447
}
435448

436449
if (

packages/core/src/codewhispererChat/clients/chat/v0/chat.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { ToolkitError } from '../../../../shared/errors'
1414
import { createCodeWhispererChatStreamingClient } from '../../../../shared/clients/codewhispererChatClient'
1515
import { createQDeveloperStreamingClient } from '../../../../shared/clients/qDeveloperChatClient'
1616
import { UserWrittenCodeTracker } from '../../../../codewhisperer/tracker/userWrittenCodeTracker'
17-
import { PromptMessage } from '../../../controllers/chat/model'
17+
import { DocumentReference, PromptMessage } from '../../../controllers/chat/model'
1818
import { FsWriteBackup } from '../../../../codewhispererChat/tools/fsWrite'
1919

2020
export type ToolUseWithError = {
@@ -30,8 +30,9 @@ export class ChatSession {
3030
* _readFiles = list of files read from the project to gather context before generating response.
3131
* _showDiffOnFileWrite = Controls whether to show diff view (true) or file context view (false) to the user
3232
* _context = Additional context to be passed to the LLM for generating the response
33+
* _messageIdToUpdate = messageId of a chat message to be updated, used for reducing consecutive tool messages
3334
*/
34-
private _readFiles: string[] = []
35+
private _readFiles: DocumentReference[] = []
3536
private _toolUseWithError: ToolUseWithError | undefined
3637
private _showDiffOnFileWrite: boolean = false
3738
private _context: PromptMessage['context']
@@ -41,6 +42,7 @@ export class ChatSession {
4142
* True if messages from local history have been sent to session.
4243
*/
4344
localHistoryHydrated: boolean = false
45+
private _messageIdToUpdate: string | undefined
4446

4547
contexts: Map<string, { first: number; second: number }[]> = new Map()
4648
// TODO: doesn't handle the edge case when two files share the same relativePath string but from different root
@@ -49,6 +51,13 @@ export class ChatSession {
4951
public get sessionIdentifier(): string | undefined {
5052
return this.sessionId
5153
}
54+
public get messageIdToUpdate(): string | undefined {
55+
return this._messageIdToUpdate
56+
}
57+
58+
public setMessageIdToUpdate(messageId: string | undefined) {
59+
this._messageIdToUpdate = messageId
60+
}
5261

5362
public get pairProgrammingModeOn(): boolean {
5463
return this._pairProgrammingModeOn
@@ -95,7 +104,7 @@ export class ChatSession {
95104
public setSessionID(id?: string) {
96105
this.sessionId = id
97106
}
98-
public get readFiles(): string[] {
107+
public get readFiles(): DocumentReference[] {
99108
return this._readFiles
100109
}
101110
public get showDiffOnFileWrite(): boolean {
@@ -104,7 +113,7 @@ export class ChatSession {
104113
public setShowDiffOnFileWrite(value: boolean) {
105114
this._showDiffOnFileWrite = value
106115
}
107-
public addToReadFiles(filePath: string) {
116+
public addToReadFiles(filePath: DocumentReference) {
108117
this._readFiles.push(filePath)
109118
}
110119
public clearListOfReadFiles() {

packages/core/src/codewhispererChat/controllers/chat/controller.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -716,9 +716,18 @@ export class ChatController {
716716
try {
717717
await ToolUtils.validate(tool)
718718

719-
const chatStream = new ChatStream(this.messenger, tabID, triggerID, toolUse, {
720-
requiresAcceptance: false,
721-
})
719+
const chatStream = new ChatStream(
720+
this.messenger,
721+
tabID,
722+
triggerID,
723+
{ ...toolUse, toolUseId: `${toolUse.toolUseId}-output` },
724+
session,
725+
undefined,
726+
false,
727+
{
728+
requiresAcceptance: false,
729+
}
730+
)
722731
if (tool.type === ToolType.FsWrite && toolUse.toolUseId) {
723732
const backup = await tool.tool.getBackup()
724733
session.setFsWriteBackup(toolUse.toolUseId, backup)

0 commit comments

Comments
 (0)