Skip to content

Commit

Permalink
Merge pull request #50 from aws/dogusata/fix-updateChatAnswerWithMess…
Browse files Browse the repository at this point in the history
…ageId-not-working

Dogusata/fix update chat answer with message id not working
  • Loading branch information
dogusata committed May 24, 2024
2 parents 3a2853f + 02ad7fd commit 9994ed2
Show file tree
Hide file tree
Showing 7 changed files with 398 additions and 434 deletions.
10 changes: 4 additions & 6 deletions example/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,17 +194,15 @@ export const createMynahUI = (initialData?: MynahUIDataModel): MynahUI => {
onFileActionClick: (tabId, messageId, filePath, actionName) => {
Log(`File action clicked: <b>${filePath}</b> -> ${actionName}`);
switch (actionName) {
case 'update-comment':
case 'comment-to-change':
showCustomForm(tabId);
break;
case 'reject-change':
mynahUI.updateChatAnswerWithMessageId(tabId, 'file-list-message', exampleFileListChatItemForUpdate);
mynahUI.updateChatAnswerWithMessageId(tabId, messageId, exampleFileListChatItemForUpdate);
break;
case 'revert-rejection':
mynahUI.updateChatAnswerWithMessageId(tabId, messageId, {fileList: exampleFileListChatItem.fileList});
break;
default:
break;
}
mynahUI.updateChatAnswerWithMessageId(tabId, 'file-list-message', exampleFileListChatItemForUpdate);
},
onCustomFormAction: (tabId, action) => {
Log(`Custom form action clicked for tab <b>${tabId}</b>:<br/>
Expand Down
739 changes: 346 additions & 393 deletions example/src/samples/sample-data.ts

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@aws/mynah-ui",
"displayName": "AWS Mynah UI",
"version": "4.9.0",
"version": "4.9.1",
"description": "AWS Toolkit VSCode and Intellij IDE Extension Mynah UI",
"publisher": "Amazon Web Services",
"license": "Apache License 2.0",
Expand Down
13 changes: 4 additions & 9 deletions src/components/chat-item/chat-item-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ChatItemFormItemsWrapper } from './chat-item-form-items';
import { ChatItemButtonsWrapper } from './chat-item-buttons';
import { cleanHtml } from '../../helper/sanitize';
import { CONTAINER_GAP } from './chat-wrapper';
import { chatItemHasContent } from '../../helper/chat-item';

const TYPEWRITER_STACK_TIME = 500;
export interface ChatItemCardProps {
Expand Down Expand Up @@ -98,15 +99,9 @@ export class ChatItemCard {
return generatedCard;
};

private readonly cardHasContent = (): boolean => ((this.props.chatItem.body != null && this.props.chatItem.body !== '') ||
this.props.chatItem.fileList != null ||
this.props.chatItem.formItems != null ||
this.props.chatItem.customRenderer != null ||
this.props.chatItem.buttons != null);

private readonly getCardClasses = (): string[] => {
const isNoContent =
!this.cardHasContent() &&
!chatItemHasContent(this.props.chatItem) &&
this.props.chatItem.followUp == null &&
this.props.chatItem.relatedContent == null &&
this.props.chatItem.type === ChatItemType.ANSWER;
Expand All @@ -115,7 +110,7 @@ export class ChatItemCard {
`mynah-chat-item-card-status-${this.props.chatItem.status ?? 'default'}`,
'mynah-chat-item-card',
`mynah-chat-item-${this.props.chatItem.type ?? ChatItemType.ANSWER}`,
...(!this.cardHasContent() ? [ 'mynah-chat-item-empty' ] : []),
...(!chatItemHasContent(this.props.chatItem) ? [ 'mynah-chat-item-empty' ] : []),
...(isNoContent ? [ 'mynah-chat-item-no-content' ] : []),
];
};
Expand Down Expand Up @@ -293,7 +288,7 @@ export class ChatItemCard {
return [
...(MynahUITabsStore.getInstance().getTabDataStore(this.props.tabId).getValue('showChatAvatars') === true ? [ this.chatAvatar ] : []),

...(this.cardHasContent()
...(chatItemHasContent(this.props.chatItem)
? [
new Card({
onCardEngaged: engagement => {
Expand Down
56 changes: 33 additions & 23 deletions src/components/chat-item/chat-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { chatItemHasContent } from '../../helper/chat-item';
import { Config } from '../../helper/config';
import { DomBuilder, ExtendedHTMLElement } from '../../helper/dom';
import { generateUID } from '../../helper/guid';
Expand All @@ -28,8 +29,8 @@ export class ChatWrapper {
private readonly promptInput: ChatPromptInput;
private readonly promptInfo: ExtendedHTMLElement;
private readonly promptStickyCard: ExtendedHTMLElement;
private lastChatItemCard: ChatItemCard | null;
private lastChatItemMessageId: string | null;
private lastStreamingChatItemCard: ChatItemCard | null;
private lastStreamingChatItemMessageId: string | null;
private allRenderedChatItems: Record<string, ChatItemCard> = {};
render: ExtendedHTMLElement;
constructor (props: ChatWrapperProps) {
Expand Down Expand Up @@ -141,31 +142,40 @@ export class ChatWrapper {
}

private readonly insertChatItem = (chatItem: ChatItem): void => {
this.lastChatItemMessageId = (chatItem.messageId != null && chatItem.messageId !== '') ? chatItem.messageId : `TEMP_${generateUID()}`;
const currentMessageId: string = (chatItem.messageId != null && chatItem.messageId !== '') ? chatItem.messageId : `TEMP_${generateUID()}`;
const chatItemCard = new ChatItemCard({
tabId: this.props.tabId,
chatItem: {
...chatItem,
messageId: this.lastChatItemMessageId
messageId: currentMessageId
}
});

if (chatItem.type === ChatItemType.ANSWER_STREAM) {
this.lastChatItemCard?.render.addClass('stream-ended');
this.lastChatItemCard = chatItemCard;
// End previous streaming card if there is
this.lastStreamingChatItemCard?.render.addClass('stream-ended');

// Update the lastStreaming variables with the new one
this.lastStreamingChatItemMessageId = currentMessageId;
this.lastStreamingChatItemCard = chatItemCard;
} else if (
(chatItem.type === ChatItemType.ANSWER ||
chatItem.type === ChatItemType.PROMPT ||
chatItem.type === ChatItemType.AI_PROMPT ||
chatItem.type === ChatItemType.SYSTEM_PROMPT) && chatItem.body !== undefined) {
this.lastChatItemCard?.render.addClass('stream-ended');
this.lastChatItemCard = null;
this.lastChatItemMessageId = null;
chatItem.type !== ChatItemType.ANSWER &&
chatItem.type !== ChatItemType.ANSWER_PART &&
chatItemHasContent(chatItem)) {
// If the new card is not a streaming one and it has any kind of content,
// it means that the last card is not a streaming card anymore.
// So end the previous stream and reset the lastStreaming variables
this.lastStreamingChatItemCard?.render.addClass('stream-ended');
this.lastStreamingChatItemCard = null;
this.lastStreamingChatItemMessageId = null;
}

// Add to render
this.chatItemsContainer.insertChild('afterbegin', chatItemCard.render);

if (this.lastChatItemMessageId != null) {
this.allRenderedChatItems[this.lastChatItemMessageId] = chatItemCard;
}
// Add to all rendered chat items map
this.allRenderedChatItems[currentMessageId] = chatItemCard;

if (chatItem.type === ChatItemType.PROMPT || chatItem.type === ChatItemType.SYSTEM_PROMPT) {
// Make sure we scroll the chat window to the bottom
// Only if it is a PROMPT
Expand All @@ -174,20 +184,20 @@ export class ChatWrapper {
};

public updateLastChatAnswer = (updateWith: Partial<ChatItem>): void => {
if (this.lastChatItemCard !== null) {
this.lastChatItemCard.updateCardStack(updateWith);
if (this.lastStreamingChatItemCard !== null) {
this.lastStreamingChatItemCard.updateCardStack(updateWith);
if (updateWith.messageId != null && updateWith.messageId !== '') {
if (this.lastChatItemMessageId != null && this.lastChatItemMessageId !== updateWith.messageId) {
const renderChatItemInMap = this.allRenderedChatItems[this.lastChatItemMessageId];
if (this.lastStreamingChatItemMessageId != null && this.lastStreamingChatItemMessageId !== updateWith.messageId) {
const renderChatItemInMap = this.allRenderedChatItems[this.lastStreamingChatItemMessageId];
if (renderChatItemInMap != null) {
this.allRenderedChatItems[updateWith.messageId] = renderChatItemInMap;
if (this.lastChatItemMessageId != null) {
if (this.lastStreamingChatItemMessageId != null) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete this.allRenderedChatItems[this.lastChatItemMessageId];
delete this.allRenderedChatItems[this.lastStreamingChatItemMessageId];
}
}
}
this.lastChatItemMessageId = updateWith.messageId;
this.lastStreamingChatItemMessageId = updateWith.messageId;
}
}
};
Expand Down
8 changes: 8 additions & 0 deletions src/helper/chat-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ChatItem } from '../static';

export const chatItemHasContent = (chatItem: Partial<ChatItem>): boolean => (
(chatItem.body != null && chatItem.body !== '') ||
chatItem.fileList != null ||
chatItem.formItems != null ||
chatItem.customRenderer != null ||
chatItem.buttons != null);

0 comments on commit 9994ed2

Please sign in to comment.