From 2b8b9255d37d10ea5109ff640f6c1f9f40048aad Mon Sep 17 00:00:00 2001 From: Alexander <98586297+Alexander-Kezik@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:09:40 +0100 Subject: [PATCH] fix(chat): change description and icon for playback and replay as is conversations start screen (Issues #2756, #2757) (#2970) --- .../chatExportImportWithAttachment.test.ts | 11 +- .../src/tests/messageTemplate.test.ts | 10 +- .../components/Chat/EmptyChatDescription.tsx | 113 ++++++++++++++---- .../components/Chat/ModelVersionSelect.tsx | 7 +- .../src/components/Chat/TalkTo/TalkToCard.tsx | 17 +-- apps/chat/src/utils/app/conversation.ts | 6 + startup.sh | 2 +- 7 files changed, 121 insertions(+), 45 deletions(-) diff --git a/apps/chat-e2e/src/tests/chatExportImportWithAttachment.test.ts b/apps/chat-e2e/src/tests/chatExportImportWithAttachment.test.ts index 8b0d4fe09..7a91aea4d 100644 --- a/apps/chat-e2e/src/tests/chatExportImportWithAttachment.test.ts +++ b/apps/chat-e2e/src/tests/chatExportImportWithAttachment.test.ts @@ -4,6 +4,7 @@ import dialTest from '@/src/core/dialFixtures'; import { API, Attachment, + ExpectedConstants, ExpectedMessages, Import, MenuOptions, @@ -542,7 +543,7 @@ dialTest( let requestDocUrl: string; await dialTest.step( - 'Prepare conversation with image, pdf attachments in the requests and replay conversation based on it', + 'Prepare conversation with image, pdf attachments in the requests and replay as is conversation based on it', async () => { requestImageUrl = await fileApiHelper.putFile(Attachment.sunImageName); requestDocUrl = await fileApiHelper.putFile(Attachment.pdfName); @@ -571,7 +572,7 @@ dialTest( ); await dialTest.step( - 'Export replay conversation with attachments', + 'Export replay as is conversation with attachments', async () => { await dialHomePage.openHomePage(); await dialHomePage.waitForPageLoaded(); @@ -589,7 +590,7 @@ dialTest( ); await dialTest.step( - 'Remove all entities, import exported file and verify replay conversation is opened', + 'Remove all entities, import exported file and verify replay as is conversation is opened', async () => { await fileApiHelper.deleteAllFiles(); await chatBar.deleteAllEntities(); @@ -603,14 +604,14 @@ dialTest( ); await agentInfoAssertion.assertElementText( agentInfo.agentName, - defaultModel.name, + ExpectedConstants.replayAsIsLabel, ); await chatAssertion.assertReplayButtonState('visible'); }, ); await dialTest.step( - 'Replay conversation and verify attachments are sent in the requests', + 'Replay as is conversation and verify attachments are sent in the requests', async () => { await dialHomePage.mockChatTextResponse( MockedChatApiResponseBodies.simpleTextBody, diff --git a/apps/chat-e2e/src/tests/messageTemplate.test.ts b/apps/chat-e2e/src/tests/messageTemplate.test.ts index af6d415cb..5e4b0af78 100644 --- a/apps/chat-e2e/src/tests/messageTemplate.test.ts +++ b/apps/chat-e2e/src/tests/messageTemplate.test.ts @@ -1012,9 +1012,13 @@ dialTest( await dialTest.step( 'Start replaying the main conversation and verify modal variable is displayed for the second conversation request', async () => { - await conversations.selectConversation(replayName, { - exactMatch: true, - }); + await conversations.selectConversation( + replayName, + { + exactMatch: true, + }, + { isHttpMethodTriggered: false }, + ); await chat.startReplay( simpleConversationMessage.messages[0].content, true, diff --git a/apps/chat/src/components/Chat/EmptyChatDescription.tsx b/apps/chat/src/components/Chat/EmptyChatDescription.tsx index 6e97cbd17..015e275fa 100644 --- a/apps/chat/src/components/Chat/EmptyChatDescription.tsx +++ b/apps/chat/src/components/Chat/EmptyChatDescription.tsx @@ -7,7 +7,10 @@ import classNames from 'classnames'; import { useScreenState } from '@/src/hooks/useScreenState'; import { getModelDescription } from '@/src/utils/app/application'; -import { getOpenAIEntityFullName } from '@/src/utils/app/conversation'; +import { + getOpenAIEntityFullName, + isOldConversationReplay, +} from '@/src/utils/app/conversation'; import { isEntityIdExternal } from '@/src/utils/app/id'; import { Conversation } from '@/src/types/chat'; @@ -25,6 +28,8 @@ import { EntityMarkdownDescription } from '../Common/MarkdownDescription'; import { Spinner } from '../Common/Spinner'; import { FunctionStatusIndicator } from '../Marketplace/FunctionStatusIndicator'; import { ModelVersionSelect } from './ModelVersionSelect'; +import { PlaybackIcon } from './Playback/PlaybackIcon'; +import { ReplayAsIsIcon } from './ReplayAsIsIcon'; import { Feature } from '@epam/ai-dial-shared'; @@ -34,6 +39,25 @@ interface EmptyChatDescriptionViewProps { onShowSettings: (show: boolean) => void; } +const getModelName = ( + conversation: Conversation, + model: DialAIEntityModel | undefined, +) => { + if (conversation.playback?.isPlayback) { + return 'Playback'; + } + + if (conversation.replay?.replayAsIs) { + return 'Replay as is'; + } + + if (model) { + return getOpenAIEntityFullName(model); + } + + return conversation.model.id; +}; + const EmptyChatDescriptionView = ({ conversation, onShowChangeModel, @@ -102,6 +126,12 @@ const EmptyChatDescriptionView = ({ } const modelIconSize = screenState === ScreenState.MOBILE ? 36 : 50; + const isOldReplay = isOldConversationReplay(conversation.replay); + const PseudoIcon = conversation.playback?.isPlayback + ? PlaybackIcon + : conversation.replay?.replayAsIs + ? ReplayAsIsIcon + : null; return (
@@ -117,46 +147,85 @@ const EmptyChatDescriptionView = ({ className="flex flex-col items-center justify-center gap-5 text-3xl leading-10" data-qa="agent-info" > - + {PseudoIcon ? ( + + ) : ( + + )}
- {model ? getOpenAIEntityFullName(model) : conversation.model.id} + {incorrectModel + ? conversation.model.id + : getModelName(conversation, model)} {model && }
- {model && ( + {conversation.replay?.replayAsIs && !incorrectModel && ( <> - - {!!getModelDescription(model) && ( - + + {t( + 'This mode replicates user requests from the original conversation including settings set in each message.', + )} + + + {isOldReplay && ( + - {getModelDescription(model)} + {t( + 'Some messages were created in an older DIAL version and may not replay as expected.', + )} )} )} + {model && + !( + conversation.playback?.isPlayback || + conversation.replay?.replayAsIs + ) && ( + <> + + {!!getModelDescription(model) && ( + + + {getModelDescription(model)} + + + )} + + )} {!isExternal && ( diff --git a/apps/chat/src/components/Chat/ModelVersionSelect.tsx b/apps/chat/src/components/Chat/ModelVersionSelect.tsx index 4eaa090a9..b92ec3ec0 100644 --- a/apps/chat/src/components/Chat/ModelVersionSelect.tsx +++ b/apps/chat/src/components/Chat/ModelVersionSelect.tsx @@ -31,15 +31,17 @@ interface ModelVersionSelectProps { currentEntity: DialAIEntity; className?: string; showVersionPrefix?: boolean; + readonly?: boolean; onSelect: (entity: DialAIEntityModel) => void; } export const ModelVersionSelect = ({ - currentEntity, entities, - onSelect, + currentEntity, className, showVersionPrefix = false, + readonly = false, + onSelect, }: ModelVersionSelectProps) => { const [isOpen, setIsOpen] = useState(false); @@ -107,6 +109,7 @@ export const ModelVersionSelect = ({ {entity.version || entity.id} } + disabled={readonly} value={entity.id} onClick={(e) => { e.stopPropagation(); diff --git a/apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx b/apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx index de76e8863..7b1047d8d 100644 --- a/apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx +++ b/apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx @@ -22,6 +22,7 @@ import { isApplicationStatusUpdating, isExecutableApp, } from '@/src/utils/app/application'; +import { isOldConversationReplay } from '@/src/utils/app/conversation'; import { getRootId } from '@/src/utils/app/id'; import { canWriteSharedWithMe } from '@/src/utils/app/share'; import { PseudoModel, isPseudoModel } from '@/src/utils/server/api'; @@ -192,18 +193,6 @@ export const TalkToCard = ({ ); }, [dispatch, entity.id]); - const isOldReplay = useMemo(() => { - return ( - entity.id === REPLAY_AS_IS_MODEL && - conversation.replay && - conversation.replay.isReplay && - conversation.replay.replayUserMessagesStack && - conversation.replay.replayUserMessagesStack.some( - (message) => !message.model, - ) - ); - }, [conversation.replay, entity.id]); - const menuItems: DisplayMenuItemProps[] = useMemo( () => [ { @@ -321,6 +310,9 @@ export const TalkToCard = ({ : screenState === ScreenState.TABLET ? TABLET_ICON_SIZE : MOBILE_ICON_SIZE; + const isOldReplay = + entity.id === REPLAY_AS_IS_MODEL && + isOldConversationReplay(conversation.replay); return (

{t('Version')}:

+ replay && + replay.isReplay && + replay.replayUserMessagesStack && + replay.replayUserMessagesStack.some((message) => !message.model); diff --git a/startup.sh b/startup.sh index de84e9f2b..916a170d0 100755 --- a/startup.sh +++ b/startup.sh @@ -2,4 +2,4 @@ KEEP_ALIVE_TIMEOUT="${KEEP_ALIVE_TIMEOUT:-61000}" -exec npm start -- --keepAliveTimeout $KEEP_ALIVE_TIMEOUT +exec npm start -- --keepAliveTimeout $KEEP_ALIVE_TIMEOUT \ No newline at end of file