From cbd7054b0d6fc837ceaf2c79287c5c5a3f036df2 Mon Sep 17 00:00:00 2001 From: Tyrone Smith Date: Fri, 4 Apr 2025 14:54:43 -0700 Subject: [PATCH 1/5] feat(amazonq): Add additonal fields for agentic chat in chat history --- .../controllers/chat/chatRequest/converter.ts | 25 ++------- .../controllers/chat/model.ts | 5 +- packages/core/src/shared/db/chatDb/chatDb.ts | 13 ++--- packages/core/src/shared/db/chatDb/util.ts | 53 +++++++++++++++++-- 4 files changed, 63 insertions(+), 33 deletions(-) diff --git a/packages/core/src/codewhispererChat/controllers/chat/chatRequest/converter.ts b/packages/core/src/codewhispererChat/controllers/chat/chatRequest/converter.ts index 896d597f796..adc95f2ef69 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/chatRequest/converter.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/chatRequest/converter.ts @@ -3,18 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { - ConversationState, - CursorState, - DocumentSymbol, - SymbolType, - TextDocument, - ChatMessage, -} from '@amzn/codewhisperer-streaming' +import { ConversationState, CursorState, DocumentSymbol, SymbolType, TextDocument } from '@amzn/codewhisperer-streaming' import { AdditionalContentEntryAddition, ChatTriggerType, RelevantTextDocumentAddition, TriggerPayload } from '../model' import { undefinedIfEmpty } from '../../../../shared/utilities/textUtilities' -import { ChatItemType } from '../../../../amazonq/commons/model' import { getLogger } from '../../../../shared/logger/logger' +import { messageToChatMessage } from '../../../../shared/db/chatDb/util' const fqnNameSizeDownLimit = 1 const fqnNameSizeUpLimit = 256 @@ -158,19 +151,7 @@ export function triggerPayloadToChatRequest(triggerPayload: TriggerPayload): { c const history = triggerPayload.history && triggerPayload.history.length > 0 && - (triggerPayload.history.map((chat) => - chat.type === ('answer' as ChatItemType) - ? { - assistantResponseMessage: { - content: chat.body, - }, - } - : { - userInputMessage: { - content: chat.body, - }, - } - ) as ChatMessage[]) + triggerPayload.history.map((chat) => messageToChatMessage(chat)) return { conversationState: { diff --git a/packages/core/src/codewhispererChat/controllers/chat/model.ts b/packages/core/src/codewhispererChat/controllers/chat/model.ts index 5c41ba95111..2613a8bd8df 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/model.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/model.ts @@ -10,7 +10,8 @@ import { Selection } from 'vscode' import { TabOpenType } from '../../../amazonq/webview/ui/storages/tabsStorage' import { CodeReference } from '../../view/connector/connector' import { Customization } from '../../../codewhisperer/client/codewhispereruserclient' -import { ChatItem, QuickActionCommand } from '@aws/mynah-ui' +import { QuickActionCommand } from '@aws/mynah-ui' +import { Message } from '../../../shared/db/chatDb/util' export interface TriggerTabIDReceived { tabID: string @@ -206,7 +207,7 @@ export interface TriggerPayload { traceId?: string contextLengths: ContextLengths workspaceRulesCount?: number - history?: ChatItem[] + history?: Message[] } export type ContextLengths = { diff --git a/packages/core/src/shared/db/chatDb/chatDb.ts b/packages/core/src/shared/db/chatDb/chatDb.ts index 43c594dc376..df936601799 100644 --- a/packages/core/src/shared/db/chatDb/chatDb.ts +++ b/packages/core/src/shared/db/chatDb/chatDb.ts @@ -5,12 +5,13 @@ import Loki from 'lokijs' import * as vscode from 'vscode' import { TabType } from '../../../amazonq/webview/ui/storages/tabsStorage' -import { ChatItem, ChatItemType, DetailedListItemGroup } from '@aws/mynah-ui' +import { ChatItemType, DetailedListItemGroup } from '@aws/mynah-ui' import { ClientType, Conversation, FileSystemAdapter, groupTabsByDate, + Message, Tab, TabCollection, updateOrCreateConversation, @@ -171,7 +172,7 @@ export class Database { const tabs = tabCollection.find() const filteredTabs = tabs.filter((tab: Tab) => { return tab.conversations.some((conversation: Conversation) => { - return conversation.messages.some((message: ChatItem) => { + return conversation.messages.some((message: Message) => { return message.body?.toLowerCase().includes(searchTermLower) }) }) @@ -225,7 +226,7 @@ export class Database { } } - addMessage(tabId: string, tabType: TabType, conversationId: string, chatItem: ChatItem) { + addMessage(tabId: string, tabType: TabType, conversationId: string, message: Message) { if (this.initialized) { const tabCollection = this.db.getCollection(TabCollection) @@ -238,9 +239,9 @@ export class Database { const tabData = historyId ? tabCollection.findOne({ historyId }) : undefined const tabTitle = - (chatItem.type === ('prompt' as ChatItemType) ? chatItem.body : tabData?.title) || 'Amazon Q Chat' + (message.type === ('prompt' as ChatItemType) ? message.body : tabData?.title) || 'Amazon Q Chat' if (tabData) { - tabData.conversations = updateOrCreateConversation(tabData.conversations, conversationId, chatItem) + tabData.conversations = updateOrCreateConversation(tabData.conversations, conversationId, message) tabData.updatedAt = new Date() tabData.title = tabTitle tabCollection.update(tabData) @@ -251,7 +252,7 @@ export class Database { isOpen: true, tabType: tabType, title: tabTitle, - conversations: [{ conversationId, clientType: ClientType.VSCode, messages: [chatItem] }], + conversations: [{ conversationId, clientType: ClientType.VSCode, messages: [message] }], }) } } diff --git a/packages/core/src/shared/db/chatDb/util.ts b/packages/core/src/shared/db/chatDb/util.ts index a176db4ff40..58232cea160 100644 --- a/packages/core/src/shared/db/chatDb/util.ts +++ b/packages/core/src/shared/db/chatDb/util.ts @@ -6,7 +6,16 @@ import fs from '../../fs/fs' import path from 'path' import { TabType } from '../../../amazonq/webview/ui/storages/tabsStorage' -import { ChatItem, ChatItemButton, DetailedListItem, DetailedListItemGroup, MynahIconsType } from '@aws/mynah-ui' +import { + ChatItemButton, + ChatItemType, + DetailedListItem, + DetailedListItemGroup, + MynahIconsType, + ReferenceTrackerInformation, + SourceLink, +} from '@aws/mynah-ui' +import { ChatMessage, Origin, ToolUse, UserInputMessageContext, UserIntent } from '@amzn/codewhisperer-streaming' export const TabCollection = 'tabs' @@ -24,7 +33,7 @@ export type Tab = { export type Conversation = { conversationId: string clientType: ClientType - messages: ChatItem[] + messages: Message[] } export enum ClientType { @@ -33,6 +42,44 @@ export enum ClientType { CLI = 'CLI', } +export type Message = { + body: string + type: ChatItemType + codeReference?: ReferenceTrackerInformation[] + relatedContent?: { + title?: string + content: SourceLink[] + } + messageId?: string + userIntent?: UserIntent + origin?: Origin + userInputMessageContext?: UserInputMessageContext + toolUses?: ToolUse[] +} + +/** + * Converts Message to CodeWhisperer Streaming ChatMessage + */ +export function messageToChatMessage(msg: Message): ChatMessage { + return msg.type.toString() === 'answer' + ? { + assistantResponseMessage: { + messageId: msg.messageId, + content: msg.body, + references: msg.codeReference || [], + toolUses: msg.toolUses || [], + }, + } + : { + userInputMessage: { + content: msg.body, + userIntent: msg.userIntent, + origin: msg.origin || 'IDE', + userInputMessageContext: msg.userInputMessageContext || {}, + }, + } +} + /** * * This adapter implements the LokiPersistenceAdapter interface for file system operations using web-compatible shared fs utils. @@ -107,7 +154,7 @@ export class FileSystemAdapter implements LokiPersistenceAdapter { export function updateOrCreateConversation( conversations: Conversation[], conversationId: string, - newMessage: ChatItem + newMessage: Message ): Conversation[] { const existingConversation = conversations.find((conv) => conv.conversationId === conversationId) From e4ac22dd6294649e847999d57be8c5ac3cb79714 Mon Sep 17 00:00:00 2001 From: Tyrone Smith Date: Fri, 4 Apr 2025 14:54:43 -0700 Subject: [PATCH 2/5] feat(amazonq): Add additonal fields for agentic chat in chat history --- .../Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json diff --git a/packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json b/packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json new file mode 100644 index 00000000000..d35f3ff9c44 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Amazon Q chat: Add additonal fields for agentic chat in chat history" +} From 9353ed79d8f39aeff0ffc2e6ba9228ffb7111130 Mon Sep 17 00:00:00 2001 From: Tyrone Smith Date: Fri, 4 Apr 2025 14:54:43 -0700 Subject: [PATCH 3/5] feat(amazonq): Add additonal fields for agentic chat in chat history --- packages/core/src/shared/db/chatDb/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/shared/db/chatDb/util.ts b/packages/core/src/shared/db/chatDb/util.ts index 94fad9c624c..1da78cf4b14 100644 --- a/packages/core/src/shared/db/chatDb/util.ts +++ b/packages/core/src/shared/db/chatDb/util.ts @@ -61,7 +61,7 @@ export type Message = { * Converts Message to CodeWhisperer Streaming ChatMessage */ export function messageToChatMessage(msg: Message): ChatMessage { - return msg.type.toString() === 'answer' + return msg.type === ('answer' as ChatItemType) ? { assistantResponseMessage: { messageId: msg.messageId, From de4b24f637ce807bbf22cb9f1296af5b3c250502 Mon Sep 17 00:00:00 2001 From: tsmithsz <84354541+tsmithsz@users.noreply.github.com> Date: Fri, 4 Apr 2025 15:38:40 -0700 Subject: [PATCH 4/5] Delete packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json --- .../Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json diff --git a/packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json b/packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json deleted file mode 100644 index d35f3ff9c44..00000000000 --- a/packages/amazonq/.changes/next-release/Feature-475cd711-2f9e-4c81-a42e-2a2fab04024a.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "Feature", - "description": "Amazon Q chat: Add additonal fields for agentic chat in chat history" -} From 3b0d82652bd3ed14393c462fc006bd3333db1b58 Mon Sep 17 00:00:00 2001 From: Tyrone Smith Date: Fri, 4 Apr 2025 15:55:30 -0700 Subject: [PATCH 5/5] fix(amazonq): Don't send agentic chat fields in the message to mynah-ui --- .../controllers/chat/tabBarController.ts | 6 ++++-- packages/core/src/shared/db/chatDb/util.ts | 13 +++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/core/src/codewhispererChat/controllers/chat/tabBarController.ts b/packages/core/src/codewhispererChat/controllers/chat/tabBarController.ts index ce0970040a2..13088e096f8 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/tabBarController.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/tabBarController.ts @@ -13,7 +13,7 @@ import * as vscode from 'vscode' import { Messenger } from './messenger/messenger' import { Database } from '../../../shared/db/chatDb/chatDb' import { TabBarButtonClick, SaveChatMessage } from './model' -import { Conversation, Tab } from '../../../shared/db/chatDb/util' +import { Conversation, messageToChatItem, Tab } from '../../../shared/db/chatDb/util' import { DetailedListItemGroup, MynahIconsType } from '@aws/mynah-ui' export class TabBarController { @@ -87,7 +87,9 @@ export class TabBarController { this.messenger.sendRestoreTabMessage( selectedTab.historyId, selectedTab.tabType, - selectedTab.conversations.flatMap((conv: Conversation) => conv.messages), + selectedTab.conversations.flatMap((conv: Conversation) => + conv.messages.map((message) => messageToChatItem(message)) + ), exportTab ) } diff --git a/packages/core/src/shared/db/chatDb/util.ts b/packages/core/src/shared/db/chatDb/util.ts index 1da78cf4b14..09ba4090b9c 100644 --- a/packages/core/src/shared/db/chatDb/util.ts +++ b/packages/core/src/shared/db/chatDb/util.ts @@ -7,6 +7,7 @@ import path from 'path' import { TabType } from '../../../amazonq/webview/ui/storages/tabsStorage' import { + ChatItem, ChatItemButton, ChatItemType, DetailedListItem, @@ -80,6 +81,18 @@ export function messageToChatMessage(msg: Message): ChatMessage { } } +/** + * Converts Message to MynahUI Chat Item + */ +export function messageToChatItem(msg: Message): ChatItem { + return { + body: msg.body, + type: msg.type as ChatItemType, + codeReference: msg.codeReference, + relatedContent: msg.relatedContent && msg.relatedContent?.content.length > 0 ? msg.relatedContent : undefined, + } +} + /** * * This adapter implements the LokiPersistenceAdapter interface for file system operations using web-compatible shared fs utils.