Skip to content

Commit

Permalink
feat(chat): integrate with publication API (Issue #1269) (#1314)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander-Kezik authored May 28, 2024
1 parent e781307 commit 95e7b12
Show file tree
Hide file tree
Showing 82 changed files with 4,174 additions and 967 deletions.
1 change: 1 addition & 0 deletions apps/chat/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ DEFAULT_MODEL="gpt-35-turbo"
DEFAULT_ASSISTANT_SUB_MODEL="gpt-4"
RECENT_MODELS_IDS="gpt-35-turbo,gpt-4,epam10k-semantic-search,gpt-world,mirror"
RECENT_ADDONS_IDS="addon-epam10k-golden-qna,addon-epam10k-semantic-search"
PUBLICATION_FILTERS="title,job title,role"

# Themes
# THEMES_CONFIG_HOST=""
Expand Down
1 change: 1 addition & 0 deletions apps/chat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ This project leverages environment variables for configuration.
| `ALLOWED_IFRAME_SOURCES` | No | Allowed iFrame Sources | Any origin valid format. List of space separated sources. | `none` |
| `IS_IFRAME` | No | Is iFrame | `true`, `false` | `false` |
| `ENABLED_FEATURES` | No | Enabled Features | See available features [here](../../libs/shared/src/types/features.ts) | |
| `PUBLICATION_FILTERS` | No | Publication Filters | Any string. Values must be separated by a comma. | `title,role` |
| `NEXT_PUBLIC_APP_NAME` | No | Public Application Name | Any string | `AI Dial` |
| `NEXT_PUBLIC_DEFAULT_SYSTEM_PROMPT` | No | Public Default System Prompt | Any string | |
| `NEXT_PUBLIC_DEFAULT_TEMPERATURE` | No | Public Default Temperature | 0 to 1 | |
Expand Down
1 change: 1 addition & 0 deletions apps/chat/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ declare global {
ALLOWED_IFRAME_SOURCES?: string;
CUSTOM_VISUALIZERS?: string;
ENABLED_FEATURES?: string;
PUBLICATION_FILTERS?: string;
NEXT_PUBLIC_APP_NAME?: string;
NEXT_PUBLIC_DEFAULT_SYSTEM_PROMPT?: string;
NEXT_PUBLIC_DEFAULT_TEMPERATURE?: string;
Expand Down
8 changes: 6 additions & 2 deletions apps/chat/src/components/Chat/ChangePathDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export const ChangePathDialog = ({
isOpen={isOpen}
modalDataQa="change-path-dialog"
onClose={() => onClose(undefined)}
title="Change path"
title={t('Change path')}
>
<SelectFolderHeader
handleSearch={handleSearch}
Expand All @@ -199,7 +199,11 @@ export const ChangePathDialog = ({
onDeleteFolder: handleDeleteFolder,
onAddFolder: handleAddFolder,
newAddedFolderId: newFolderId,
featureType: FeatureType.File,
featureType:
type === SharingType.Conversation ||
type === SharingType.ConversationFolder
? FeatureType.Chat
: FeatureType.Prompt,
}}
handleFolderSelect={handleFolderSelect}
isAllEntitiesOpened={isAllFoldersOpened}
Expand Down
9 changes: 9 additions & 0 deletions apps/chat/src/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
ModelsSelectors,
} from '@/src/store/models/models.reducers';
import { PromptsSelectors } from '@/src/store/prompts/prompts.reducers';
import { PublicationSelectors } from '@/src/store/publication/publication.reducers';
import { SettingsSelectors } from '@/src/store/settings/settings.reducers';
import { UISelectors } from '@/src/store/ui/ui.reducers';

Expand All @@ -52,6 +53,7 @@ import { ErrorMessageDiv } from './ErrorMessageDiv';
import { MemoizedChatMessage } from './MemoizedChatMessage';
import { NotAllowedModel } from './NotAllowedModel';
import { PlaybackControls } from './Playback/PlaybackControls';
import { HandlePublication } from './Publish/HandlePublication';
import { StartReplayButton } from './StartReplayButton';

import { Feature } from '@epam/ai-dial-shared';
Expand Down Expand Up @@ -933,6 +935,13 @@ export function Chat() {
const activeModel = useAppSelector((state) =>
ModelsSelectors.selectModel(state, isolatedModelId || ''),
);
const selectedPublication = useAppSelector(
PublicationSelectors.selectSelectedPublication,
);

if (selectedPublication?.resources && !selectedConversationsIds.length) {
return <HandlePublication publication={selectedPublication} />;
}

if (isolatedModelId && modelIsLoaded && !activeModel) {
return (
Expand Down
23 changes: 22 additions & 1 deletion apps/chat/src/components/Chat/ChatExternalControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,43 @@ import { ConversationInfo } from '@/src/types/chat';
import { Translation } from '@/src/types/translation';

import { ConversationsActions } from '@/src/store/conversations/conversations.reducers';
import { useAppDispatch } from '@/src/store/hooks';
import { useAppDispatch, useAppSelector } from '@/src/store/hooks';
import { PublicationSelectors } from '@/src/store/publication/publication.reducers';

import { PublicationControls } from './Publish/PublicationChatControls';

interface Props {
conversations: ConversationInfo[];
}

export default function ChatExternalControls({ conversations }: Props) {
const { t } = useTranslation(Translation.Chat);

const dispatch = useAppDispatch();

const resourceToReview = useAppSelector((state) =>
PublicationSelectors.selectResourceToReviewByReviewUrl(
state,
conversations[0]?.id,
),
);

const handleDuplicate = useCallback(() => {
conversations.forEach((conv) => {
dispatch(ConversationsActions.duplicateConversation(conv));
});
}, [conversations, dispatch]);

if (conversations.length === 1 && resourceToReview) {
return (
<PublicationControls
resourceToReview={resourceToReview}
entity={conversations[0]}
wrapperClassName="justify-center w-full"
/>
);
}

return (
<button
className="button button-chat !-top-10"
Expand Down
28 changes: 23 additions & 5 deletions apps/chat/src/components/Chat/ChatInput/PromptList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { useDismiss, useFloating, useInteractions } from '@floating-ui/react';
import { FC, useEffect } from 'react';
import { FC, useEffect, useMemo } from 'react';

import classNames from 'classnames';

import { FeatureType } from '@/src/types/common';
import { Prompt } from '@/src/types/prompt';

import { useAppSelector } from '@/src/store/hooks';
import { PublicationSelectors } from '@/src/store/publication/publication.reducers';

interface Props {
prompts: Prompt[];
activePromptIndex: number;
Expand All @@ -26,6 +32,12 @@ export const PromptList: FC<Props> = ({
onClose();
},
});
const promptResources = useAppSelector((state) =>
PublicationSelectors.selectFilteredPublicationResources(
state,
FeatureType.Prompt,
),
);

const dismiss = useDismiss(context);
const { getFloatingProps } = useInteractions([dismiss]);
Expand All @@ -36,19 +48,25 @@ export const PromptList: FC<Props> = ({
}
}, [activePromptIndex, refs.floating]);

const filteredPrompts = useMemo(() => {
const publicationPromptUrls = promptResources.map((r) => r.reviewUrl);
return prompts.filter((p) => !publicationPromptUrls.includes(p.id));
}, [promptResources, prompts]);

return (
<ul
ref={refs.setFloating}
{...getFloatingProps()}
className="z-10 max-h-52 w-full overflow-auto rounded bg-layer-3"
data-qa="prompt-list"
>
{prompts.map((prompt, index) => (
{filteredPrompts.map((prompt, index) => (
<li
key={prompt.id}
className={`${
index === activePromptIndex ? 'bg-accent-primary-alpha' : ''
} cursor-pointer px-3 py-2`}
className={classNames(
'cursor-pointer px-3 py-2',
index === activePromptIndex && 'bg-accent-primary-alpha',
)}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
Expand Down
100 changes: 48 additions & 52 deletions apps/chat/src/components/Chat/ChatSettingsEmpty.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,59 +51,55 @@ export const ChatSettingsEmpty = ({
const modelsMap = useAppSelector(ModelsSelectors.selectModelsMap);

return (
<>
<div className="flex size-full flex-col items-center p-0 md:px-5 md:pt-5">
<div className="flex size-full flex-col items-center gap-[1px] rounded 2xl:max-w-[1000px]">
{!isModels ? (
<div className="flex w-full items-center justify-center rounded-t bg-layer-2 p-4">
<Spinner size={16} className="mx-auto" />
</div>
) : (
<>
{appName && (
<div className="flex w-full items-center justify-center rounded-t bg-layer-2 p-4">
<h4
data-qa="app-name"
className="w-full whitespace-pre text-center text-xl font-semibold"
>
{isolatedModelId && modelsMap[isolatedModelId] ? (
<ModelDescription
model={modelsMap[isolatedModelId] as DialAIEntityModel}
className="justify-center"
hideMoreInfo
isShortDescription
/>
) : (
appName
)}
</h4>
</div>
)}
</>
)}
<div className="flex size-full flex-col items-center p-0 md:px-5 md:pt-5">
<div className="flex size-full flex-col items-center gap-[1px] rounded 2xl:max-w-[1000px]">
{!isModels ? (
<div className="flex w-full items-center justify-center rounded-t bg-layer-2 p-4">
<Spinner size={16} className="mx-auto" />
</div>
) : (
<>
{appName && (
<div className="flex w-full items-center justify-center rounded-t bg-layer-2 p-4">
<h4
data-qa="app-name"
className="w-full whitespace-pre text-center text-xl font-semibold"
>
{isolatedModelId && modelsMap[isolatedModelId] ? (
<ModelDescription
model={modelsMap[isolatedModelId] as DialAIEntityModel}
className="justify-center"
hideMoreInfo
isShortDescription
/>
) : (
appName
)}
</h4>
</div>
)}
</>
)}

{isShowSettings && isModels && (
<>
<ConversationSettings
conversation={conversation}
modelId={conversation.model.id}
assistantModelId={conversation.assistantModelId}
prompt={conversation.prompt}
selectedAddons={conversation.selectedAddons}
temperature={conversation.temperature}
prompts={prompts}
onChangePrompt={onChangePrompt}
onChangeTemperature={onChangeTemperature}
onSelectAssistantSubModel={onSelectAssistantSubModel}
onSelectModel={onSelectModel}
onChangeAddon={onChangeAddon}
onApplyAddons={handleOnApplyAddons}
debounceSystemPromptChanges
/>
</>
)}
</div>
{isShowSettings && isModels && (
<ConversationSettings
conversation={conversation}
modelId={conversation.model.id}
assistantModelId={conversation.assistantModelId}
prompt={conversation.prompt}
selectedAddons={conversation.selectedAddons}
temperature={conversation.temperature}
prompts={prompts}
onChangePrompt={onChangePrompt}
onChangeTemperature={onChangeTemperature}
onSelectAssistantSubModel={onSelectAssistantSubModel}
onSelectModel={onSelectModel}
onChangeAddon={onChangeAddon}
onApplyAddons={handleOnApplyAddons}
debounceSystemPromptChanges
/>
)}
</div>
</>
</div>
);
};
Loading

0 comments on commit 95e7b12

Please sign in to comment.