Skip to content

Commit 87284a8

Browse files
committed
feat(amazonq): Use Chat History DB instead of in-memory store
1 parent 529da80 commit 87284a8

File tree

6 files changed

+129
-322
lines changed

6 files changed

+129
-322
lines changed

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

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@ import { createQDeveloperStreamingClient } from '../../../../shared/clients/qDev
1616
import { UserWrittenCodeTracker } from '../../../../codewhisperer/tracker/userWrittenCodeTracker'
1717
import { PromptMessage } from '../../../controllers/chat/model'
1818
import { FsWriteBackup } from '../../../../codewhispererChat/tools/fsWrite'
19+
import { randomUUID } from '../../../../shared/crypto'
1920

2021
export type ToolUseWithError = {
2122
toolUse: ToolUse
2223
error: Error | undefined
2324
}
24-
import { getLogger } from '../../../../shared/logger/logger'
25-
import { randomUUID } from '../../../../shared/crypto'
2625

2726
export class ChatSession {
28-
private sessionId?: string
27+
private sessionId: string
2928
/**
3029
* _readFiles = list of files read from the project to gather context before generating response.
3130
* _showDiffOnFileWrite = Controls whether to show diff view (true) or file context view (false) to the user
@@ -46,7 +45,7 @@ export class ChatSession {
4645
// TODO: doesn't handle the edge case when two files share the same relativePath string but from different root
4746
// e.g. root_a/file1 vs root_b/file1
4847
relativePathToWorkspaceRoot: Map<string, string> = new Map()
49-
public get sessionIdentifier(): string | undefined {
48+
public get sessionIdentifier(): string {
5049
return this.sessionId
5150
}
5251

@@ -86,13 +85,14 @@ export class ChatSession {
8685

8786
constructor() {
8887
this.createNewTokenSource()
88+
this.sessionId = randomUUID()
8989
}
9090

9191
createNewTokenSource() {
9292
this.tokenSource = new vscode.CancellationTokenSource()
9393
}
9494

95-
public setSessionID(id?: string) {
95+
public setSessionID(id: string) {
9696
this.sessionId = id
9797
}
9898
public get readFiles(): string[] {
@@ -120,14 +120,6 @@ export class ChatSession {
120120
)
121121
}
122122

123-
const responseStream = response.sendMessageResponse
124-
for await (const event of responseStream) {
125-
if ('messageMetadataEvent' in event) {
126-
this.sessionId = event.messageMetadataEvent?.conversationId
127-
break
128-
}
129-
}
130-
131123
UserWrittenCodeTracker.instance.onQFeatureInvoked()
132124
return response
133125
}
@@ -142,12 +134,6 @@ export class ChatSession {
142134
)
143135
}
144136

145-
this.sessionId = response.conversationId
146-
if (this.sessionId?.length === 0) {
147-
getLogger().debug(`Session ID: ${this.sessionId} is empty. Generating random UUID`)
148-
this.sessionId = randomUUID()
149-
}
150-
151137
UserWrittenCodeTracker.instance.onQFeatureInvoked()
152138

153139
return response

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

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ import { amazonQTabSuffix } from '../../../shared/constants'
9696
import { OutputKind } from '../../tools/toolShared'
9797
import { ToolUtils, Tool, ToolType } from '../../tools/toolUtils'
9898
import { ChatStream } from '../../tools/chatStream'
99-
import { ChatHistoryStorage } from '../../storages/chatHistoryStorage'
10099
import { tempDirPath } from '../../../shared/filesystemUtilities'
101100
import { Database } from '../../../shared/db/chatDb/chatDb'
102101
import { TabBarController } from './tabBarController'
102+
import { messageToChatMessage } from '../../../shared/db/chatDb/util'
103103

104104
export interface ChatControllerMessagePublishers {
105105
readonly processPromptChatMessage: MessagePublisher<PromptMessage>
@@ -174,7 +174,6 @@ export class ChatController {
174174
private readonly userIntentRecognizer: UserIntentRecognizer
175175
private readonly telemetryHelper: CWCTelemetryHelper
176176
private userPromptsWatcher: vscode.FileSystemWatcher | undefined
177-
private readonly chatHistoryStorage: ChatHistoryStorage
178177
private chatHistoryDb = Database.getInstance()
179178

180179
public constructor(
@@ -193,7 +192,6 @@ export class ChatController {
193192
this.editorContentController = new EditorContentController()
194193
this.promptGenerator = new PromptsGenerator()
195194
this.userIntentRecognizer = new UserIntentRecognizer()
196-
this.chatHistoryStorage = new ChatHistoryStorage()
197195
this.tabBarController = new TabBarController(this.messenger)
198196

199197
onDidChangeAmazonQVisibility((visible) => {
@@ -408,7 +406,7 @@ export class ChatController {
408406
const session = this.sessionStorage.getSession(message.tabID)
409407
session.tokenSource.cancel()
410408
this.messenger.sendEmptyMessage(message.tabID, '', undefined)
411-
this.chatHistoryStorage.getTabHistory(message.tabID).clearRecentHistory()
409+
this.chatHistoryDb.clearRecentHistory(message.tabID)
412410
}
413411

414412
private async processTriggerTabIDReceived(message: TriggerTabIDReceived) {
@@ -465,7 +463,6 @@ export class ChatController {
465463

466464
private async processTabCloseMessage(message: TabClosedMessage) {
467465
this.sessionStorage.deleteSession(message.tabID)
468-
this.chatHistoryStorage.deleteHistory(message.tabID)
469466
this.triggerEventsStorage.removeTabEvents(message.tabID)
470467
// this.telemetryHelper.recordCloseChat(message.tabID)
471468
this.chatHistoryDb.updateTabOpenState(message.tabID, false)
@@ -1000,7 +997,7 @@ export class ChatController {
1000997
getLogger().error(`error: ${errorMessage} tabID: ${tabID} requestID: ${requestID}`)
1001998

1002999
this.sessionStorage.deleteSession(tabID)
1003-
this.chatHistoryStorage.getTabHistory(tabID).clearRecentHistory()
1000+
this.chatHistoryDb.clearRecentHistory(tabID)
10041001
}
10051002

10061003
private async processContextMenuCommand(command: EditorContextCommand) {
@@ -1121,7 +1118,6 @@ export class ChatController {
11211118
switch (message.command) {
11221119
case 'clear':
11231120
this.sessionStorage.deleteSession(message.tabID)
1124-
this.chatHistoryStorage.getTabHistory(message.tabID).clear()
11251121
this.triggerEventsStorage.removeTabEvents(message.tabID)
11261122
recordTelemetryChatRunCommand('clear')
11271123
this.chatHistoryDb.clearTab(message.tabID)
@@ -1193,8 +1189,6 @@ export class ChatController {
11931189
context,
11941190
})
11951191

1196-
this.messenger.sendAsyncEventProgress(message.tabID, true, '')
1197-
11981192
await this.generateResponse(
11991193
{
12001194
message: message.message ?? '',
@@ -1410,10 +1404,6 @@ export class ChatController {
14101404
}
14111405

14121406
const session = this.sessionStorage.getSession(tabID)
1413-
if (!session.localHistoryHydrated) {
1414-
triggerPayload.history = this.chatHistoryDb.getMessages(triggerEvent.tabID, 10)
1415-
session.localHistoryHydrated = true
1416-
}
14171407
await this.resolveContextCommandPayload(triggerPayload, session)
14181408
triggerPayload.useRelevantDocuments = triggerPayload.context.some(
14191409
(context) => typeof context !== 'string' && context.command === '@workspace'
@@ -1452,16 +1442,14 @@ export class ChatController {
14521442

14531443
const request = triggerPayloadToChatRequest(triggerPayload)
14541444

1455-
const chatHistory = this.chatHistoryStorage.getTabHistory(tabID)
14561445
const currentMessage = request.conversationState.currentMessage
14571446
if (currentMessage) {
1458-
chatHistory.fixHistory(currentMessage)
1447+
this.chatHistoryDb.fixHistory(tabID, currentMessage)
14591448
}
1460-
request.conversationState.history = chatHistory.getHistory()
1461-
1462-
const conversationId = chatHistory.getConversationId() || randomUUID()
1463-
chatHistory.setConversationId(conversationId)
1464-
request.conversationState.conversationId = conversationId
1449+
request.conversationState.history = this.chatHistoryDb
1450+
.getMessages(tabID, 100)
1451+
.map((chat) => messageToChatMessage(chat))
1452+
request.conversationState.conversationId = session.sessionIdentifier
14651453

14661454
triggerPayload.documentReferences = this.mergeRelevantTextDocuments(triggerPayload.relevantTextDocuments)
14671455

@@ -1501,6 +1489,7 @@ export class ChatController {
15011489
session.setContext(triggerPayload.context)
15021490
}
15031491
this.messenger.sendInitalStream(tabID, triggerID)
1492+
this.messenger.sendAsyncEventProgress(tabID, true, '')
15041493
this.telemetryHelper.setConversationStreamStartTime(tabID)
15051494
if (isSsoConnection(AuthUtil.instance.conn)) {
15061495
const { $metadata, generateAssistantResponseResponse } = await session.chatSso(request)
@@ -1519,7 +1508,6 @@ export class ChatController {
15191508
this.telemetryHelper.recordStartConversation(triggerEvent, triggerPayload)
15201509

15211510
if (currentMessage && session.sessionIdentifier) {
1522-
chatHistory.appendUserMessage(currentMessage)
15231511
this.chatHistoryDb.addMessage(tabID, 'cwc', session.sessionIdentifier, {
15241512
body: triggerPayload.message,
15251513
type: 'prompt' as any,
@@ -1534,7 +1522,7 @@ export class ChatController {
15341522
response.$metadata.requestId
15351523
} metadata: ${inspect(response.$metadata, { depth: 12 })}`
15361524
)
1537-
await this.messenger.sendAIResponse(response, session, tabID, triggerID, triggerPayload, chatHistory)
1525+
await this.messenger.sendAIResponse(response, session, tabID, triggerID, triggerPayload)
15381526

15391527
// Turn off AgentLoop flag after sending the AI response
15401528
this.sessionStorage.setAgentLoopInProgress(tabID, false)

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

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ import {
5656
} from '@aws/mynah-ui'
5757
import { Database } from '../../../../shared/db/chatDb/chatDb'
5858
import { TabType } from '../../../../amazonq/webview/ui/storages/tabsStorage'
59-
import { ChatHistoryManager } from '../../../storages/chatHistory'
6059
import { ToolType, ToolUtils } from '../../../tools/toolUtils'
6160
import { ChatStream } from '../../../tools/chatStream'
6261
import path from 'path'
@@ -182,8 +181,7 @@ export class Messenger {
182181
session: ChatSession,
183182
tabID: string,
184183
triggerID: string,
185-
triggerPayload: TriggerPayload,
186-
chatHistoryManager: ChatHistoryManager
184+
triggerPayload: TriggerPayload
187185
) {
188186
let message = ''
189187
const messageID = response.$metadata.requestId ?? ''
@@ -469,17 +467,6 @@ export class Messenger {
469467
tabID
470468
)
471469
)
472-
473-
chatHistoryManager.pushAssistantMessage({
474-
assistantResponseMessage: {
475-
messageId: messageID,
476-
content: message,
477-
references: codeReference,
478-
...(toolUse &&
479-
toolUse.input !== undefined &&
480-
toolUse.input !== '' && { toolUses: [{ ...toolUse }] }),
481-
},
482-
})
483470
const agenticLoopEnded = !eventCounts.has('toolUseEvent')
484471
if (agenticLoopEnded) {
485472
// Reset context for the next request

0 commit comments

Comments
 (0)