Skip to content

Commit dfee9f7

Browse files
authored
fix(chat): agentic chat working stop (aws#6950)
## Problem Conversation needs stop button to stop the agentic chat loop and conversations topping for new user prompt. ## Solution - Enables prompt when chat loop is running for new user prompt. - Fixes chat history for stop/user prompts and followup prompts. --- - 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 1ca2650 commit dfee9f7

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export interface ConnectorProps extends BaseConnectorProps {
3232
inProgress: boolean,
3333
message: string,
3434
messageId: string | undefined,
35-
enableStopAction: boolean
35+
enableStopAction: boolean,
36+
isPromptInputDisabled: boolean
3637
) => void
3738
}
3839

@@ -259,7 +260,8 @@ export class Connector extends BaseConnector {
259260
messageData.inProgress,
260261
messageData.message ?? undefined,
261262
messageData.messageId ?? undefined,
262-
enableStopAction
263+
enableStopAction,
264+
false
263265
)
264266
return
265267
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,13 @@ export const createMynahUI = (
300300
inProgress: boolean,
301301
message: string | undefined,
302302
messageId: string | undefined = undefined,
303-
enableStopAction: boolean = false
303+
enableStopAction: boolean = false,
304+
isPromptInputDisabled: boolean = true
304305
) => {
305306
if (inProgress) {
306307
mynahUI.updateStore(tabID, {
307308
loadingChat: true,
308-
promptInputDisabledState: true,
309+
promptInputDisabledState: isPromptInputDisabled,
309310
cancelButtonWhenLoading: enableStopAction,
310311
})
311312

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ export class ChatController {
408408
private async processStopResponseMessage(message: StopResponseMessage) {
409409
const session = this.sessionStorage.getSession(message.tabID)
410410
session.tokenSource.cancel()
411+
this.messenger.sendEmptyMessage(message.tabID, '', undefined)
411412
this.chatHistoryStorage.getTabHistory(message.tabID).clearRecentHistory()
412413
}
413414

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,4 +785,28 @@ export class Messenger {
785785
public sendAsyncEventProgress(tabID: string, inProgress: boolean, message: string | undefined) {
786786
this.dispatcher.sendAsyncEventProgress(new AsyncEventProgressMessage(tabID, 'CWChat', inProgress, message))
787787
}
788+
789+
public sendEmptyMessage(
790+
tabID: string,
791+
triggerId: string,
792+
mergedRelevantDocuments: DocumentReference[] | undefined
793+
) {
794+
this.dispatcher.sendChatMessage(
795+
new ChatMessage(
796+
{
797+
message: '',
798+
messageType: 'answer',
799+
followUps: undefined,
800+
followUpsHeader: undefined,
801+
relatedSuggestions: undefined,
802+
triggerID: triggerId,
803+
messageID: '',
804+
userIntent: undefined,
805+
codeBlockLanguage: undefined,
806+
contextList: undefined,
807+
},
808+
tabID
809+
)
810+
)
811+
}
788812
}

packages/core/src/codewhispererChat/storages/chatHistory.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,13 @@ export class ChatHistoryManager {
8080
* Push an assistant message to the history
8181
*/
8282
public pushAssistantMessage(newMessage: ChatMessage): void {
83-
if (newMessage !== undefined && this.lastUserMessage !== undefined) {
84-
this.logger.warn('last Message should not be defined when pushing an assistant message')
83+
if (newMessage !== undefined && this.lastUserMessage === undefined) {
84+
this.logger.warn('first assistant response should always come after user input message')
85+
return
86+
}
87+
// check if last message in histroy is assistant message and now replace it in that case
88+
if (this.history.length > 0 && this.history.at(-1)?.assistantResponseMessage) {
89+
this.history.pop()
8590
}
8691
this.history.push(newMessage)
8792
}
@@ -101,6 +106,18 @@ export class ChatHistoryManager {
101106
}
102107

103108
private trimConversationHistory(): void {
109+
// make sure the UseInputMessage is the first stored message
110+
if (this.history.length === 1 && this.history[0].assistantResponseMessage) {
111+
this.history = []
112+
}
113+
114+
if (
115+
this.history.at(-1)?.assistantResponseMessage?.content === '' &&
116+
this.history.at(-1)?.assistantResponseMessage?.toolUses === undefined
117+
) {
118+
this.clearRecentHistory()
119+
}
120+
104121
if (this.history.length <= MaxConversationHistoryLength) {
105122
return
106123
}

0 commit comments

Comments
 (0)