├── .npmrc ├── .gitattributes ├── apps ├── overlay-sandbox │ ├── public │ │ ├── .gitkeep │ │ └── favicon.ico │ ├── .env.development │ ├── tailwind.config.js │ ├── index.d.ts │ ├── postcss.config.js │ ├── app │ │ ├── cases │ │ │ ├── components │ │ │ │ └── backToSelectOverlayMode.tsx │ │ │ └── overlay │ │ │ │ ├── disabled-all-features-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-only-header-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-only-header-footer-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-hide-user-settings-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-hide-empty-change-agent-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-only-header-conversations-section-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── edit-last-assistant-message │ │ │ │ └── page.tsx │ │ │ │ ├── disabled-top-chat-info-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-disallow-change-agent-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-hide-top-context-menu-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-only-footer-links-attachments-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── disabled-marketplace-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-input-files-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-empty-chat-settings-sandbox │ │ │ │ └── page.tsx │ │ │ │ ├── disabled-default-buttons │ │ │ │ └── page.tsx │ │ │ │ ├── enabled-marketplace-sandbox │ │ │ │ └── page.tsx │ │ │ │ └── overlay-conversation-id-set-sandbox │ │ │ │ └── page.tsx │ │ ├── global.css │ │ └── layout.tsx │ ├── .eslintrc.json │ ├── README.md │ └── next.config.js ├── custom-viewer-test │ ├── public │ │ ├── .gitkeep │ │ └── favicon.ico │ ├── .env.development │ ├── tailwind.config.js │ ├── app │ │ ├── global.css │ │ └── layout.tsx │ ├── index.d.ts │ ├── environment.d.ts │ ├── postcss.config.js │ ├── .eslintrc.json │ └── next.config.js ├── chat-e2e │ ├── src │ │ ├── testData │ │ │ ├── attachments │ │ │ │ ├── test1.txt │ │ │ │ ├── text.txt │ │ │ │ ├── sun.jpg │ │ │ │ ├── cloud.jpg │ │ │ │ ├── flower.jpg │ │ │ │ ├── heart.webp │ │ │ │ ├── image.png │ │ │ │ ├── test1.jpg │ │ │ │ ├── test10.jpg │ │ │ │ ├── test11.jpg │ │ │ │ ├── test12.jpg │ │ │ │ ├── test13.jpg │ │ │ │ ├── test14.jpg │ │ │ │ ├── test15.jpg │ │ │ │ ├── test2.jpg │ │ │ │ ├── test3.jpg │ │ │ │ ├── test4.jpg │ │ │ │ ├── test5.jpg │ │ │ │ ├── test6.jpg │ │ │ │ ├── test7.jpg │ │ │ │ ├── test8.jpg │ │ │ │ ├── test9.jpg │ │ │ │ ├── testdot..JPg │ │ │ │ ├── withoutExtension │ │ │ │ ├── pdf_attachment.pdf │ │ │ │ ├── restricted;char.jpg │ │ │ │ ├── restricted=,;{}%&.JPG │ │ │ │ ├── restricted=char.jpg │ │ │ │ ├── special (`~!@#$^-_+[]'.).jpg │ │ │ │ └── attachmentWithVeryVeryVeryVeryVeryLongTitleDescription.jpg │ │ │ ├── import │ │ │ │ └── ai_dial_chat_with_attachments.dial │ │ │ ├── api │ │ │ │ ├── index.ts │ │ │ │ └── bucketApiHelper.ts │ │ │ ├── applications │ │ │ │ └── customApplicationBuilder.ts │ │ │ ├── injector │ │ │ │ └── dataInjectorInterface.ts │ │ │ └── index.ts │ │ ├── ui │ │ │ ├── domData │ │ │ │ ├── properties.ts │ │ │ │ ├── index.ts │ │ │ │ └── tags.ts │ │ │ ├── selectors │ │ │ │ ├── commonSelectors.ts │ │ │ │ ├── fileSelectors.ts │ │ │ │ ├── notFoundSelectors.ts │ │ │ │ ├── entitySelectors.ts │ │ │ │ ├── editSelectors.ts │ │ │ │ ├── index.ts │ │ │ │ ├── headerSelectors.ts │ │ │ │ ├── folderSelectors.ts │ │ │ │ └── loginSelectors.ts │ │ │ ├── pages │ │ │ │ ├── index.ts │ │ │ │ ├── DialErrorPage.ts │ │ │ │ ├── loginPage.ts │ │ │ │ └── overlay │ │ │ │ │ ├── overlayMarketplacePage.ts │ │ │ │ │ └── overlayLoginPage.ts │ │ │ ├── webElements │ │ │ │ ├── topicsTooltip.ts │ │ │ │ ├── dropdownButtonMenu.ts │ │ │ │ ├── chatLoader.ts │ │ │ │ ├── dropdownCheckboxMenu.ts │ │ │ │ ├── entityEditor │ │ │ │ │ ├── externalApp │ │ │ │ │ │ └── externalAppEditorViewForm.ts │ │ │ │ │ ├── base │ │ │ │ │ │ ├── entitySettings │ │ │ │ │ │ │ ├── entityEditorViewForm.ts │ │ │ │ │ │ │ ├── entityEditorEntitySettingsPreviewBody.ts │ │ │ │ │ │ │ └── entityEditorEntitySettingsPreviewHeader.ts │ │ │ │ │ │ ├── entityEditorForm.ts │ │ │ │ │ │ └── general │ │ │ │ │ │ │ └── entityEditorPreviewToggle.ts │ │ │ │ │ └── customApp │ │ │ │ │ │ ├── customAppEditorAppSettingsPreviewBody.ts │ │ │ │ │ │ └── customAppEditorAppSettingsPreview.ts │ │ │ │ ├── common │ │ │ │ │ └── button.ts │ │ │ │ ├── overlay │ │ │ │ │ └── dialog.ts │ │ │ │ ├── modalError.ts │ │ │ │ ├── tooltip.ts │ │ │ │ ├── entityTree │ │ │ │ │ ├── publication │ │ │ │ │ │ ├── publishFolderFiles.ts │ │ │ │ │ │ ├── publishFolderPrompts.ts │ │ │ │ │ │ ├── publishFolderConversations.ts │ │ │ │ │ │ ├── publishApplicationsTree.ts │ │ │ │ │ │ ├── publishConversationsTree.ts │ │ │ │ │ │ └── publishPromptsTree.ts │ │ │ │ │ └── sidebar │ │ │ │ │ │ ├── sharedFolderConversations.ts │ │ │ │ │ │ ├── promptsTree.ts │ │ │ │ │ │ ├── organizationPromptsTree.ts │ │ │ │ │ │ ├── sharedWithMeConversationsTree.ts │ │ │ │ │ │ ├── approveRequiredPrompts.ts │ │ │ │ │ │ ├── organizationConversationsTree.ts │ │ │ │ │ │ ├── sharedWithMePromptsTree.ts │ │ │ │ │ │ └── approveRequiredConversationsTree.ts │ │ │ │ ├── importExportLoader.ts │ │ │ │ ├── chatNotFound.ts │ │ │ │ ├── footer │ │ │ │ │ ├── reportAnIssueModal.ts │ │ │ │ │ └── requestApiKeyModal.ts │ │ │ │ ├── toast.ts │ │ │ │ ├── errorPopup.ts │ │ │ │ ├── footer.ts │ │ │ │ ├── changePath.ts │ │ │ │ ├── notFound.ts │ │ │ │ ├── publishedPromptPreviewModal.ts │ │ │ │ ├── banner.ts │ │ │ │ ├── editInputActions.ts │ │ │ │ ├── baseLayoutContainer.ts │ │ │ │ └── auth0.ts │ │ │ ├── actions │ │ │ │ ├── loginInterface.ts │ │ │ │ ├── auth0Login.ts │ │ │ │ ├── keycloakLogin.ts │ │ │ │ └── azureADLogin.ts │ │ │ └── keyboard.ts │ │ ├── utils │ │ │ ├── regexUtil.ts │ │ │ ├── index.ts │ │ │ ├── userUtil.ts │ │ │ ├── applicationsUtil.ts │ │ │ └── themesUtil.ts │ │ ├── hooks │ │ │ └── global-teardown.ts │ │ └── assertions │ │ │ ├── promptAssertion.ts │ │ │ ├── messageTemplateModalAssertion.ts │ │ │ ├── manageAttachmentFoldersAssertion.ts │ │ │ ├── publishing │ │ │ └── publishedPromptPreviewModalAssertion.ts │ │ │ ├── conversationInfoTooltipAssertion.ts │ │ │ ├── conversationAssertion.ts │ │ │ ├── conversationToCompareAssertion.ts │ │ │ ├── accountSettingsAssertion.ts │ │ │ └── selectFolderModalAssertion.ts │ ├── .env.development │ ├── config │ │ └── monitoring.playwright.config.ts │ └── .eslintrc.json └── chat │ ├── public │ ├── locales │ │ └── en │ │ │ ├── common.json │ │ │ ├── markdown.json │ │ │ ├── settings.json │ │ │ ├── promptbar.json │ │ │ └── chat.json │ ├── images │ │ ├── banners │ │ │ ├── welcome-dark.jpg │ │ │ ├── welcome-light.jpg │ │ │ ├── welcome-dark-my-apps.jpg │ │ │ ├── welcome-light-my-apps.jpg │ │ │ └── chat-announcement-banner.webp │ │ └── icons │ │ │ ├── radio-checked.svg │ │ │ ├── arrow-up-right.svg │ │ │ ├── download.svg │ │ │ ├── arrow-narrow-down.svg │ │ │ ├── move-left.svg │ │ │ ├── move-right.svg │ │ │ ├── chevron-down.svg │ │ │ ├── chevron-up.svg │ │ │ ├── plus-large.svg │ │ │ ├── check.svg │ │ │ ├── circle-check.svg │ │ │ ├── refresh-cw.svg │ │ │ ├── refresh-cw-alt.svg │ │ │ ├── rotate.svg │ │ │ ├── user.svg │ │ │ ├── search-alt.svg │ │ │ ├── insert-prompt.svg │ │ │ ├── unshare-user.svg │ │ │ ├── arrow-up-right-from-square.svg │ │ │ ├── play.svg │ │ │ ├── key.svg │ │ │ ├── file-arrow-right.svg │ │ │ ├── caret-down.svg │ │ │ ├── caret-right.svg │ │ │ ├── message-square-lines-alt.svg │ │ │ ├── folder-plus.svg │ │ │ └── unpublish.svg │ └── scripts │ │ └── theme-loader.js │ ├── src │ ├── constants │ │ ├── share.ts │ │ ├── versions.ts │ │ ├── talkTo.ts │ │ ├── footer.ts │ │ ├── icons.ts │ │ ├── sidebars.ts │ │ ├── drag-and-drop.ts │ │ ├── replay.ts │ │ ├── external-apps.ts │ │ ├── client-data.ts │ │ ├── file.ts │ │ ├── publication.ts │ │ ├── search.ts │ │ ├── successMessages.ts │ │ ├── themes.ts │ │ ├── routes.ts │ │ ├── folders.ts │ │ ├── toolsets.ts │ │ └── default-server-settings.ts │ ├── components │ │ ├── Promptbar │ │ │ ├── index.ts │ │ │ └── components │ │ │ │ └── PromptDialogs │ │ │ │ └── index.tsx │ │ ├── Common │ │ │ ├── AgentDialogs.tsx │ │ │ ├── ToolsetDialogs.tsx │ │ │ ├── DateRenderer.tsx │ │ │ ├── ToggleSwitch │ │ │ │ └── view-props.ts │ │ │ ├── ApplicationWizard │ │ │ │ └── form.ts │ │ │ ├── DisableOverlay.tsx │ │ │ ├── ReplaceConfirmationModal │ │ │ │ └── ReplaceRowContainer.tsx │ │ │ ├── ErrorTooltip.tsx │ │ │ ├── Spinner.tsx │ │ │ ├── Loader.tsx │ │ │ ├── FilesSelector │ │ │ │ └── NoFiles.tsx │ │ │ ├── NoData.tsx │ │ │ ├── ScrollDownButton.tsx │ │ │ └── ScreenRender.tsx │ │ ├── Chat │ │ │ ├── MemoizedChatMessage.tsx │ │ │ ├── Publish │ │ │ │ ├── PublicationHandler │ │ │ │ │ └── ReviewRowItems │ │ │ │ │ │ ├── view-props.ts │ │ │ │ │ │ ├── PublicationFileRow.tsx │ │ │ │ │ │ └── PublicationPromptRow.tsx │ │ │ │ ├── PublicationControls │ │ │ │ │ └── view-props.ts │ │ │ │ └── ReviewDot.tsx │ │ │ ├── BlinkingCursor.tsx │ │ │ ├── IconNonModelWithTooltip.tsx │ │ │ ├── ChatInput │ │ │ │ ├── ChatInputFooter.tsx │ │ │ │ └── SchemaCompareWarning.tsx │ │ │ └── ChatCompareRotate.tsx │ │ ├── Chatbar │ │ │ └── ConversationDialogs │ │ │ │ └── index.tsx │ │ ├── Markdown │ │ │ └── MemoizedReactMarkdown.tsx │ │ ├── Header │ │ │ └── User │ │ │ │ └── User.tsx │ │ ├── Marketplace │ │ │ ├── Rating │ │ │ │ └── RatingProgressBar.tsx │ │ │ ├── MarketplaceEntitiesList │ │ │ │ └── view-props.ts │ │ │ ├── MarketplaceEntityTopic.tsx │ │ │ └── MarketplaceEditorView │ │ │ │ └── marketplaceEditorViewContext.ts │ │ ├── Plotly │ │ │ └── PlotlyStringDataRenderer.tsx │ │ ├── Sidebar │ │ │ └── ResizeIcons.tsx │ │ ├── Badge.tsx │ │ ├── Buttons │ │ │ ├── CloseSidebarButton.tsx │ │ │ └── SidebarActionButton.tsx │ │ ├── Files │ │ │ └── Download.tsx │ │ └── Title.tsx │ ├── store │ │ ├── service │ │ │ ├── service.types.ts │ │ │ └── service.selectors.ts │ │ ├── auth │ │ │ ├── auth.types.ts │ │ │ └── auth.reducers.ts │ │ ├── folders │ │ │ ├── folders.types.ts │ │ │ └── folders.selectors.ts │ │ ├── codeEditor │ │ │ └── codeEditor.types.ts │ │ ├── hooks.ts │ │ ├── applicationTypeSchemas │ │ │ └── applicationTypeSchemas.types.ts │ │ ├── migration │ │ │ └── migration.types.ts │ │ ├── chat │ │ │ └── chat.types.ts │ │ ├── overlay │ │ │ └── overlay.types.ts │ │ ├── files │ │ │ └── files.types.ts │ │ ├── toolset │ │ │ └── toolset.types.ts │ │ └── application │ │ │ └── applications.types.ts │ ├── utils │ │ ├── auth │ │ │ ├── delay.ts │ │ │ ├── timeout-async.ts │ │ │ └── auth-pages.ts │ │ ├── app │ │ │ ├── themes.ts │ │ │ ├── permissions.ts │ │ │ ├── translation.ts │ │ │ ├── clear-messages-state.ts │ │ │ ├── epics-helpers │ │ │ │ └── application.epic-helpers.ts │ │ │ ├── style-helpers.ts │ │ │ ├── errors.ts │ │ │ ├── tokenizer.ts │ │ │ ├── attachments.ts │ │ │ ├── keyboard.ts │ │ │ ├── __tests__ │ │ │ │ └── file.test.ts │ │ │ ├── data │ │ │ │ └── bucket-service.ts │ │ │ └── sidebar.ts │ │ ├── json.ts │ │ ├── session.ts │ │ └── server │ │ │ └── logger.ts │ ├── types │ │ ├── report-issue.ts │ │ ├── form-schema.ts │ │ ├── toasts.ts │ │ ├── prompt.ts │ │ ├── import-export.ts │ │ ├── talkTo.ts │ │ ├── http.ts │ │ ├── settings.ts │ │ ├── custom-visualizers.ts │ │ ├── request-api-key.ts │ │ ├── translation.ts │ │ ├── themes.ts │ │ ├── modal.ts │ │ ├── store.ts │ │ ├── search.ts │ │ ├── parse-entity.ts │ │ └── folder.ts │ ├── instrumentation.ts │ ├── customizations │ │ └── index.tsx │ ├── pages │ │ └── api │ │ │ ├── health.ts │ │ │ ├── ops │ │ │ └── [...slug].ts │ │ │ └── toolsets-listing │ │ │ ├── index.ts │ │ │ └── [...slug].ts │ └── hooks │ │ ├── useResizeObserver.ts │ │ ├── useLogout.ts │ │ ├── useScreenState.ts │ │ ├── useTranslation.ts │ │ └── useUrlHash.ts │ ├── postcss.config.js │ ├── next-i18next.config.js │ ├── tests │ └── setupTests.ts │ └── index.d.ts ├── docs └── ai-dial-chat.png ├── .dockerignore ├── libs ├── shared │ ├── src │ │ ├── constants │ │ │ ├── index.ts │ │ │ └── visualizer-connector.ts │ │ ├── index.ts │ │ ├── utils │ │ │ ├── index.ts │ │ │ ├── features.ts │ │ │ ├── styleUtils.ts │ │ │ ├── __tests__ │ │ │ │ └── features.test.ts │ │ │ └── Task.ts │ │ └── types │ │ │ ├── overlay │ │ │ ├── index.ts │ │ │ ├── conversation.ts │ │ │ └── events.ts │ │ │ ├── common.ts │ │ │ ├── prompt.ts │ │ │ ├── index.ts │ │ │ ├── json-schema.ts │ │ │ └── visualizer-connector.ts │ ├── .eslintrc.json │ ├── README.md │ ├── tsconfig.lib.json │ ├── package.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ └── vite.config.ts ├── modulify-ui │ ├── .eslintrc.json │ ├── src │ │ ├── index.ts │ │ └── lib │ │ │ └── utils │ │ │ ├── common.ts │ │ │ └── appWithJss.tsx │ ├── tsconfig.lib.json │ ├── package.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ └── vite.config.ts ├── visualizer-connector │ ├── src │ │ └── index.ts │ ├── tsconfig.lib.json │ ├── tsconfig.json │ ├── package.json │ ├── tsconfig.spec.json │ └── README.md ├── chat-visualizer-connector │ ├── src │ │ └── index.ts │ ├── tsconfig.lib.json │ ├── tsconfig.json │ ├── package.json │ └── tsconfig.spec.json └── overlay │ ├── tsconfig.lib.json │ ├── tsconfig.json │ ├── package.json │ └── tsconfig.spec.json ├── .trivyignore ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ └── config.yml ├── workflows │ ├── release.yml │ ├── cleanup-untagged-images.yml │ ├── pr.yml │ ├── pr-title-check.yml │ └── e2e_tests.yml └── dependabot.yml ├── .prettierignore ├── .eslintignore ├── .editorconfig ├── CONTRIBUTING.md ├── prettier.config.js └── trivy.yaml /.npmrc: -------------------------------------------------------------------------------- 1 | legacy-peer-deps=true -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/public/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/public/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test1.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/chat/public/locales/en/common.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /apps/chat/public/locales/en/markdown.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /apps/chat/public/locales/en/settings.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /apps/chat/public/locales/en/promptbar.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/text.txt: -------------------------------------------------------------------------------- 1 | test text 2 | -------------------------------------------------------------------------------- /apps/chat/src/constants/share.ts: -------------------------------------------------------------------------------- 1 | export const SHARE_QUERY_PARAM = 'share'; 2 | -------------------------------------------------------------------------------- /apps/chat/src/components/Promptbar/index.ts: -------------------------------------------------------------------------------- 1 | export { Promptbar } from './Promptbar'; 2 | -------------------------------------------------------------------------------- /docs/ai-dial-chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/docs/ai-dial-chat.png -------------------------------------------------------------------------------- /apps/chat/src/constants/versions.ts: -------------------------------------------------------------------------------- 1 | export const validVersionRegEx = /^\d+\.\d+\.\d+(-\w+\.\d+)?/; 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | test-results 3 | e2e 4 | helm 5 | .next 6 | .env 7 | .env.local 8 | .git 9 | docs -------------------------------------------------------------------------------- /libs/shared/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './overlay'; 2 | export * from './visualizer-connector'; 3 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/.env.development: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_VIEWER_HOST="*" 2 | NEXT_PUBLIC_APP_NAME="Custom Viewer app" 3 | -------------------------------------------------------------------------------- /libs/shared/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"] 4 | } 5 | -------------------------------------------------------------------------------- /libs/shared/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './utils'; 3 | export * from './constants'; 4 | -------------------------------------------------------------------------------- /libs/modulify-ui/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../.eslintrc.json"], 3 | "ignorePatterns": ["!**/*"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/chat/src/constants/talkTo.ts: -------------------------------------------------------------------------------- 1 | export const SuggestedCard = { 2 | id: 'suggested', 3 | reference: 'suggested', 4 | }; 5 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/.env.development: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_OVERLAY_HOST="http://localhost:3000" 2 | NEXT_PUBLIC_OVERLAY_USER_BUCKET= 3 | -------------------------------------------------------------------------------- /apps/chat/src/store/service/service.types.ts: -------------------------------------------------------------------------------- 1 | export interface ServiceState { 2 | isSuccessfullySent: true | undefined; 3 | } 4 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/overlay-sandbox/public/favicon.ico -------------------------------------------------------------------------------- /apps/chat/src/utils/auth/delay.ts: -------------------------------------------------------------------------------- 1 | export const delay = (delay: number) => 2 | new Promise((resolve) => setTimeout(resolve, delay)); 3 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/custom-viewer-test/public/favicon.ico -------------------------------------------------------------------------------- /apps/chat/src/constants/footer.ts: -------------------------------------------------------------------------------- 1 | export const requestApiKeyHash = '#requestApiKey'; 2 | export const reportAnIssueHash = '#reportAnIssue'; 3 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/sun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/sun.jpg -------------------------------------------------------------------------------- /apps/chat/src/constants/icons.ts: -------------------------------------------------------------------------------- 1 | export const ICON_TO_CONTAINER_RATIO_NUMERATOR = 7; 2 | export const ICON_TO_CONTAINER_RATIO_DENOMINATOR = 8; 3 | -------------------------------------------------------------------------------- /apps/chat/src/constants/sidebars.ts: -------------------------------------------------------------------------------- 1 | export const SIDEBAR_DISPLAY_ITEM_INCREMENT = 50; 2 | export const DEFAULT_SIDEBAR_DISPLAY_ITEM_COUNT = 100; 3 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/cloud.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/cloud.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/flower.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/flower.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/heart.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/heart.webp -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/image.png -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test1.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test10.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test11.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test12.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test13.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test14.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test15.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test2.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test3.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test4.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test5.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test6.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test7.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test8.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/test9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/test9.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/domData/properties.ts: -------------------------------------------------------------------------------- 1 | export enum Properties { 2 | selectionStart = 'selectionStart', 3 | scrollTop = 'scrollTop', 4 | } 5 | -------------------------------------------------------------------------------- /apps/chat/public/images/banners/welcome-dark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat/public/images/banners/welcome-dark.jpg -------------------------------------------------------------------------------- /apps/chat/public/images/banners/welcome-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat/public/images/banners/welcome-light.jpg -------------------------------------------------------------------------------- /apps/chat/src/types/report-issue.ts: -------------------------------------------------------------------------------- 1 | export interface ReportIssueBody { 2 | title: string; 3 | description: string; 4 | email: string; 5 | } 6 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/testdot..JPg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/testdot..JPg -------------------------------------------------------------------------------- /apps/chat/src/constants/drag-and-drop.ts: -------------------------------------------------------------------------------- 1 | export const emptyImage = 2 | 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; 3 | -------------------------------------------------------------------------------- /libs/shared/README.md: -------------------------------------------------------------------------------- 1 | # DIAL Shared 2 | 3 | DIAL Shared is a library for using shared types and functionality across different DIAL libraries and apps. 4 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/withoutExtension: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/withoutExtension -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/domData/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tags'; 2 | export * from './attributes'; 3 | export * from './styles'; 4 | export * from './colors'; 5 | -------------------------------------------------------------------------------- /apps/chat/src/constants/replay.ts: -------------------------------------------------------------------------------- 1 | import { Replay } from '@epam/ai-dial-shared'; 2 | 3 | export const defaultReplay: Replay = { 4 | isReplay: false, 5 | }; 6 | -------------------------------------------------------------------------------- /apps/chat/src/types/form-schema.ts: -------------------------------------------------------------------------------- 1 | export enum FormSchemaPropertyType { 2 | Button = 'button', 3 | Checkbox = 'checkbox', 4 | Unknown = 'unknown', 5 | } 6 | -------------------------------------------------------------------------------- /libs/shared/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './features'; 2 | export * from './Task'; 3 | export * from './DeferredRequest'; 4 | export * from './styleUtils'; 5 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/pdf_attachment.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/pdf_attachment.pdf -------------------------------------------------------------------------------- /apps/chat/public/images/banners/welcome-dark-my-apps.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat/public/images/banners/welcome-dark-my-apps.jpg -------------------------------------------------------------------------------- /apps/chat/public/images/banners/welcome-light-my-apps.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat/public/images/banners/welcome-light-my-apps.jpg -------------------------------------------------------------------------------- /apps/chat/src/constants/external-apps.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_EXTERNAL_APPS_SCHEMA_ID = 2 | 'https://mydial.epam.com/custom_application_schemas/externalapps'; 3 | -------------------------------------------------------------------------------- /libs/visualizer-connector/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/VisualizerConnector'; 2 | 3 | export { type VisualizerConnectorOptions } from '@epam/ai-dial-shared'; 4 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/restricted;char.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/restricted;char.jpg -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/restricted=,;{}%&.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/restricted=,;{}%&.JPG -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/restricted=char.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/restricted=char.jpg -------------------------------------------------------------------------------- /apps/chat/public/images/banners/chat-announcement-banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat/public/images/banners/chat-announcement-banner.webp -------------------------------------------------------------------------------- /apps/chat/src/instrumentation.ts: -------------------------------------------------------------------------------- 1 | export async function register() { 2 | if (process.env.NEXT_RUNTIME === 'nodejs') { 3 | await import('./opentelemetry'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ['./app/**/*.{js,ts,jsx,tsx,mdx}'], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [], 7 | }; 8 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/special (`~!@#$^-_+[]'.).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/special (`~!@#$^-_+[]'.).jpg -------------------------------------------------------------------------------- /apps/chat/src/types/toasts.ts: -------------------------------------------------------------------------------- 1 | export enum ToastType { 2 | Success = 'success', 3 | Error = 'error', 4 | Warning = 'warning', 5 | Info = 'info', 6 | Loading = 'loading', 7 | } 8 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ['./app/**/*.{js,ts,jsx,tsx,mdx}'], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [], 7 | }; 8 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/import/ai_dial_chat_with_attachments.dial: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/import/ai_dial_chat_with_attachments.dial -------------------------------------------------------------------------------- /apps/chat/src/customizations/index.tsx: -------------------------------------------------------------------------------- 1 | export const useCustomizations = () => { 2 | // You may add here customizations for the app 3 | // read more: libs/modulify-ui/README.md 4 | }; 5 | -------------------------------------------------------------------------------- /.trivyignore: -------------------------------------------------------------------------------- 1 | # false-positives in esbuild 2 | # https://github.com/evanw/esbuild/issues/4257 3 | CVE-2025-4674 exp:2026-01-01 4 | CVE-2025-47907 exp:2026-01-01 5 | CVE-2025-43865 exp:2026-01-01 6 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/utils/regexUtil.ts: -------------------------------------------------------------------------------- 1 | export class RegexUtil { 2 | static escapeRegexChars(str: string): string { 3 | return str.replace(/[-/\\^$*+?.()|[\]{}']/g, '\\$&'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /apps/chat/src/store/auth/auth.types.ts: -------------------------------------------------------------------------------- 1 | import { SessionContextValue } from 'next-auth/react'; 2 | 3 | export interface AuthState { 4 | session: SessionContextValue | undefined; 5 | } 6 | -------------------------------------------------------------------------------- /apps/chat/src/types/prompt.ts: -------------------------------------------------------------------------------- 1 | export type { PromptInfo, Prompt } from '@epam/ai-dial-shared'; 2 | 3 | export interface TemplateParameter { 4 | name: string; 5 | defaultValue: string; 6 | } 7 | -------------------------------------------------------------------------------- /libs/shared/src/types/overlay/index.ts: -------------------------------------------------------------------------------- 1 | export * from './conversation'; 2 | export * from './overlay'; 3 | export * from './response'; 4 | export * from './request'; 5 | export * from './events'; 6 | -------------------------------------------------------------------------------- /apps/chat/public/scripts/theme-loader.js: -------------------------------------------------------------------------------- 1 | try { 2 | document.documentElement.className = JSON.parse(localStorage.getItem('settings') || '{}').theme || ''; 3 | } catch(e) { 4 | console.error(e); 5 | } -------------------------------------------------------------------------------- /libs/modulify-ui/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/ComponentBuilder'; 2 | export * from './lib/Inversify'; 3 | export * from './lib/utils/appWithJss'; 4 | export * from './lib/utils/documentWithJss'; 5 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/AgentDialogs.tsx: -------------------------------------------------------------------------------- 1 | import { ApplicationLogs } from './ApplicationLogs'; 2 | 3 | export const AgentDialogs = () => ( 4 | <> 5 | 6 | 7 | ); 8 | -------------------------------------------------------------------------------- /libs/chat-visualizer-connector/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/ChatVisualizerConnector'; 2 | export { 3 | type AttachmentData, 4 | type CustomVisualizerDataLayout, 5 | } from '@epam/ai-dial-shared'; 6 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/hooks/global-teardown.ts: -------------------------------------------------------------------------------- 1 | import { FileUtil } from '@/src/utils'; 2 | 3 | async function globalTeardown() { 4 | FileUtil.deleteExportFolder(); 5 | } 6 | 7 | export default globalTeardown; 8 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/app/global.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: white; 3 | height: 100vh; 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | -------------------------------------------------------------------------------- /libs/shared/src/utils/features.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '../types/features'; 2 | 3 | export const validateFeature = (feature: string) => { 4 | return Object.values(Feature).includes(feature as Feature); 5 | }; 6 | -------------------------------------------------------------------------------- /apps/chat/src/constants/client-data.ts: -------------------------------------------------------------------------------- 1 | export const CLIENTDATA_PATH = 'clientdata'; 2 | export const INSTALLED_DEPLOYMENTS = 'installed_deployments.json'; 3 | export const INSTALLED_TOOLSETS = 'installed_toolsets.json'; 4 | -------------------------------------------------------------------------------- /apps/chat/src/pages/api/health.ts: -------------------------------------------------------------------------------- 1 | import { NextApiRequest, NextApiResponse } from 'next'; 2 | 3 | export default function handler(_: NextApiRequest, res: NextApiResponse) { 4 | res.status(200).send('Healthy'); 5 | } 6 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | declare module '*.svg' { 3 | const content: any; 4 | export const ReactComponent: any; 5 | export default content; 6 | } 7 | -------------------------------------------------------------------------------- /libs/shared/src/types/overlay/conversation.ts: -------------------------------------------------------------------------------- 1 | import { ConversationInfo } from '../chat'; 2 | 3 | export type OverlayConversation = ConversationInfo & { 4 | bucket: string; 5 | parentPath?: string | null; 6 | }; 7 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | declare module '*.svg' { 3 | const content: any; 4 | export const ReactComponent: any; 5 | export default content; 6 | } 7 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @Gimir @denys-kolomiitsev @Alexander-Kezik @IlyaBondar @Derikyan 2 | /.github/ @nepalevov @alexey-ban @IlyaBondar 3 | /apps/chat-e2e/ @irinakartun @nartovm 4 | /apps/overlay-sandbox-e2e/ @irinakartun @nartovm 5 | -------------------------------------------------------------------------------- /apps/chat/src/types/import-export.ts: -------------------------------------------------------------------------------- 1 | export enum Operation { 2 | Importing = 'Importing', 3 | Exporting = 'Exporting', 4 | } 5 | 6 | export enum ImportRoot { 7 | Imports = 'imports', 8 | Files = 'files', 9 | } 10 | -------------------------------------------------------------------------------- /libs/shared/src/types/common.ts: -------------------------------------------------------------------------------- 1 | export interface DialLibRequest { 2 | type: string; 3 | requestId: string; 4 | payload?: unknown; 5 | } 6 | 7 | export type Styles = { [property in keyof CSSStyleDeclaration]?: string }; 8 | -------------------------------------------------------------------------------- /libs/shared/src/types/prompt.ts: -------------------------------------------------------------------------------- 1 | import { ShareEntity } from './chat'; 2 | 3 | export type PromptInfo = ShareEntity; 4 | 5 | export interface Prompt extends PromptInfo { 6 | description?: string; 7 | content?: string; 8 | } 9 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/MemoizedChatMessage.tsx: -------------------------------------------------------------------------------- 1 | import { FC, memo } from 'react'; 2 | 3 | import { ChatMessage, Props } from './ChatMessage/ChatMessage'; 4 | 5 | export const MemoizedChatMessage: FC = memo(ChatMessage); 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/.git 2 | **/.svn 3 | **/.hg 4 | **/node_modules 5 | 6 | .next/ 7 | next.config.js 8 | next-i18next.config.js 9 | public 10 | 11 | dist 12 | 13 | .github 14 | helm 15 | 16 | /coverage 17 | 18 | /.nx/cache 19 | -------------------------------------------------------------------------------- /apps/chat/src/constants/file.ts: -------------------------------------------------------------------------------- 1 | export const MIME_FORMAT_REGEX = 2 | /^([a-zA-Z0-9!*\-.+]+|\*)\/([a-zA-Z0-9!*\-.+]+|\*)$/; 3 | 4 | export const BYTES_IN_MB = 1_048_576; 5 | 6 | export const MAX_FILE_SIZE_IN_BYTES = BYTES_IN_MB * 512; 7 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/attachments/attachmentWithVeryVeryVeryVeryVeryLongTitleDescription.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epam/ai-dial-chat/HEAD/apps/chat-e2e/src/testData/attachments/attachmentWithVeryVeryVeryVeryVeryLongTitleDescription.jpg -------------------------------------------------------------------------------- /apps/chat/src/components/Common/ToolsetDialogs.tsx: -------------------------------------------------------------------------------- 1 | import { ToolsetLoginDialog } from '@/src/components/Marketplace/ToolsetLoginDialog'; 2 | 3 | export const ToolsetDialogs = () => ( 4 | <> 5 | 6 | 7 | ); 8 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/themes.ts: -------------------------------------------------------------------------------- 1 | import { isAbsoluteUrl } from './file'; 2 | 3 | export const getThemeIconUrl = (iconUrl: string) => 4 | isAbsoluteUrl(iconUrl) 5 | ? iconUrl 6 | : `/api/themes/image/${encodeURIComponent(iconUrl)}`; 7 | -------------------------------------------------------------------------------- /apps/chat/src/store/folders/folders.types.ts: -------------------------------------------------------------------------------- 1 | import { TemporaryFolderInterface } from '@epam/ai-dial-shared'; 2 | 3 | export interface FoldersState { 4 | temporaryFolders: TemporaryFolderInterface[]; 5 | newAddedTemporaryFolderId: string; 6 | } 7 | -------------------------------------------------------------------------------- /apps/chat/postcss.config.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path'); 2 | 3 | module.exports = { 4 | plugins: { 5 | tailwindcss: { 6 | config: join(__dirname, 'tailwind.config.js'), 7 | }, 8 | autoprefixer: {}, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/environment.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | namespace NodeJS { 5 | interface ProcessEnv { 6 | NEXT_PUBLIC_VIEWER_HOST: string; 7 | NEXT_PUBLIC_APP_NAME: string; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/chat/src/constants/publication.ts: -------------------------------------------------------------------------------- 1 | export const PUBLIC_URL_PREFIX = 'public'; 2 | export const NA_VERSION = 'N/A'; 3 | export const DEFAULT_VERSION = '0.0.1'; 4 | 5 | export enum PUBLICATION_QUERY_PARAMS { 6 | publicationUrl = 'publicationUrl', 7 | } 8 | -------------------------------------------------------------------------------- /apps/chat/src/pages/api/ops/[...slug].ts: -------------------------------------------------------------------------------- 1 | import { createDialApiSlugsHandler } from '@/src/utils/server/api-slug-handler'; 2 | 3 | export default createDialApiSlugsHandler({ 4 | generalErrorMessage: 'Operation failed', 5 | pathParameter: 'ops', 6 | }); 7 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/commonSelectors.ts: -------------------------------------------------------------------------------- 1 | import { Attributes, Tags } from '@/src/ui/domData'; 2 | 3 | export const ButtonSelectors = { 4 | buttonContainer: (ariaLabel: string) => 5 | `${Tags.button}[${Attributes.ariaLabel}="${ariaLabel}"]`, 6 | }; 7 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/postcss.config.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path'); 2 | 3 | module.exports = { 4 | plugins: { 5 | tailwindcss: { 6 | config: join(__dirname, 'tailwind.config.js'), 7 | }, 8 | autoprefixer: {}, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/postcss.config.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path'); 2 | 3 | module.exports = { 4 | plugins: { 5 | tailwindcss: { 6 | config: join(__dirname, 'tailwind.config.js'), 7 | }, 8 | autoprefixer: {}, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/Publish/PublicationHandler/ReviewRowItems/view-props.ts: -------------------------------------------------------------------------------- 1 | import { ShareEntity } from '@epam/ai-dial-shared'; 2 | 3 | export interface PublicationItemProps { 4 | item: ShareEntity; 5 | level: number; 6 | publicationUrl: string; 7 | } 8 | -------------------------------------------------------------------------------- /apps/chat/src/types/talkTo.ts: -------------------------------------------------------------------------------- 1 | import { SuggestedCard } from '@/src/constants/talkTo'; 2 | 3 | import { DialAIEntityModel } from './models'; 4 | 5 | type SuggestedCardType = typeof SuggestedCard; 6 | 7 | export type CardType = DialAIEntityModel | SuggestedCardType; 8 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/radio-checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/fileSelectors.ts: -------------------------------------------------------------------------------- 1 | export const FileSelectors = { 2 | loadingIndicator: '[data-qa="attachment-loading"]', 3 | loadingRetry: '[data-qa="retry-upload"]', 4 | fileTypeAttribute: '[type="file"]', 5 | downloadIcon: '[data-qa="download"]', 6 | }; 7 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/arrow-up-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/constants/search.ts: -------------------------------------------------------------------------------- 1 | import { getEntitySearchOptions } from '@/src/utils/app/search'; 2 | 3 | import { MarketplaceEntity } from '@/src/types/marketplace'; 4 | 5 | export const MARKETPLACE_ENTITIES_SEARCH_OPTIONS = 6 | getEntitySearchOptions(); 7 | -------------------------------------------------------------------------------- /apps/chat/src/types/http.ts: -------------------------------------------------------------------------------- 1 | export enum HTTPMethod { 2 | CONNECT = 'CONNECT', 3 | DELETE = 'DELETE', 4 | GET = 'GET', 5 | HEAD = 'HEAD', 6 | OPTIONS = 'OPTIONS', 7 | PATCH = 'PATCH', 8 | POST = 'POST', 9 | PUT = 'PUT', 10 | TRACE = 'TRACE', 11 | } 12 | -------------------------------------------------------------------------------- /apps/chat/src/types/settings.ts: -------------------------------------------------------------------------------- 1 | export interface Settings { 2 | theme: string; 3 | } 4 | 5 | export interface LastConversationSettings { 6 | temperature: number; 7 | } 8 | 9 | export enum EnterType { 10 | Enter = 'Enter', 11 | CtrlEnter = 'CtrlEnter', 12 | } 13 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/promptAssertion.ts: -------------------------------------------------------------------------------- 1 | import { SideBarEntityAssertion } from '@/src/assertions/sideBarEntityAssertion'; 2 | import { PromptsTree } from '@/src/ui/webElements/entityTree'; 3 | 4 | export class PromptAssertion extends SideBarEntityAssertion {} 5 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/pages/index.ts: -------------------------------------------------------------------------------- 1 | export * from './basePage'; 2 | export * from './dialHomePage'; 3 | export * from './loginPage'; 4 | export * from './azureADPage'; 5 | export * from './marketplacePage'; 6 | export * from './keycloakPage'; 7 | export * from './entityEditorPage'; 8 | -------------------------------------------------------------------------------- /apps/chat/src/types/custom-visualizers.ts: -------------------------------------------------------------------------------- 1 | export interface CustomVisualizer { 2 | title: string; 3 | description: string; 4 | icon: string; 5 | contentType: string; 6 | url: string; 7 | } 8 | 9 | export type MappedVisualizers = Record; 10 | -------------------------------------------------------------------------------- /apps/chat/next-i18next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | i18n: { 3 | defaultLocale: 'en', 4 | locales: ['en'], 5 | }, 6 | localePath: 7 | typeof window === 'undefined' 8 | ? require('path').resolve('./public/locales') 9 | : '/public/locales', 10 | }; 11 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/pages/api/toolsets-listing/index.ts: -------------------------------------------------------------------------------- 1 | import { createApiHandler } from '@/src/utils/server/api-handler'; 2 | 3 | import { HTTPMethod } from '@/src/types/http'; 4 | 5 | export default createApiHandler({ 6 | endpoint: '/openai/toolsets', 7 | method: HTTPMethod.GET, 8 | }); 9 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/components/backToSelectOverlayMode.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | export function BackToButton() { 4 | return ( 5 | 6 | Back to select Overlay mode 7 | 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/arrow-narrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chatbar/ConversationDialogs/index.tsx: -------------------------------------------------------------------------------- 1 | import { ConversationMoveToDialog } from './ConversationMoveToDialog'; 2 | 3 | export const ConversationDialogs: React.FC = () => { 4 | return ( 5 | <> 6 | 7 | 8 | ); 9 | }; 10 | -------------------------------------------------------------------------------- /apps/chat/src/types/request-api-key.ts: -------------------------------------------------------------------------------- 1 | export interface RequestAPIKeyBody { 2 | project_id: string; 3 | project_stream: string; 4 | project_end: string; 5 | business_reason: string; 6 | workload_pattern: string; 7 | access_scenario: string; 8 | project_lead: string; 9 | } 10 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/permissions.ts: -------------------------------------------------------------------------------- 1 | import { isEntityIdLocal } from './id'; 2 | 3 | import { Entity, SharePermission } from '@epam/ai-dial-shared'; 4 | 5 | export const isEntityReadOnly = (entity: Entity) => 6 | !entity.permissions?.includes(SharePermission.WRITE) && 7 | !isEntityIdLocal(entity); 8 | -------------------------------------------------------------------------------- /libs/shared/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/move-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/move-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/DateRenderer.tsx: -------------------------------------------------------------------------------- 1 | import { formatDate } from '@/src/utils/app/common'; 2 | 3 | interface DateProps { 4 | dateValue: number | string | Date; 5 | } 6 | 7 | export function DateRenderer({ dateValue }: DateProps) { 8 | return {formatDate(dateValue)}; 9 | } 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/.git 2 | **/.svn 3 | **/.hg 4 | **/node_modules 5 | 6 | .next 7 | next.config.js 8 | next-i18next.config.js 9 | public 10 | 11 | dist 12 | 13 | .github 14 | helm 15 | apps/chat-e2e/html-report 16 | apps/chat-e2e/chat-html-report 17 | apps/chat-e2e/overlay-html-report 18 | next-env.d.ts 19 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/chevron-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/chevron-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/plus-large.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/chat/src/constants/successMessages.ts: -------------------------------------------------------------------------------- 1 | export const successMessages = { 2 | importSuccess: 'imported successfully', 3 | importAttachmentsSuccess: 'Attachment(s) imported successfully', 4 | importAttachmentsSuccessConversationIgnored: 5 | 'Conversation ignored. Attachment(s) imported successfully', 6 | }; 7 | -------------------------------------------------------------------------------- /apps/chat/tests/setupTests.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom/vitest'; 2 | import { configure } from '@testing-library/react'; 3 | 4 | import '@/src/styles/globals.css'; 5 | 6 | // use "data-qa" instead of "data-testid" to share it with e2e tests 7 | configure({ 8 | testIdAttribute: 'data-qa', 9 | }); 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/chat/src/constants/themes.ts: -------------------------------------------------------------------------------- 1 | import { ThemesConfig } from '@/src/types/themes'; 2 | 3 | export const FALLBACK_THEME_CONFIG: ThemesConfig = { 4 | themes: [], 5 | images: {}, 6 | }; 7 | 8 | export const DEFAULT_MODEL_IMAGE = 'default-model'; 9 | export const DEFAULT_TOOLSET_IMAGE = 'default-toolset'; 10 | -------------------------------------------------------------------------------- /libs/overlay/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | As an open-source project in a rapidly developing field, we are extremely open to contributions, whether it be in the form of a new feature, improved infrastructure, or better documentation. 2 | 3 | For detailed information on how to contribute, see [here](https://github.com/epam/ai-dial/blob/main/CONTRIBUTING.md). 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/ToggleSwitch/view-props.ts: -------------------------------------------------------------------------------- 1 | export interface ToggleSwitchProps { 2 | isOn: boolean; 3 | handleSwitch: () => void; 4 | switchOnText?: string; 5 | switchOFFText?: string; 6 | additionalText?: string; 7 | className?: string; 8 | disabled?: boolean; 9 | tooltip?: string; 10 | } 11 | -------------------------------------------------------------------------------- /apps/chat/src/pages/api/toolsets-listing/[...slug].ts: -------------------------------------------------------------------------------- 1 | import { createDialApiSlugsHandler } from '@/src/utils/server/api-slug-handler'; 2 | 3 | export default createDialApiSlugsHandler({ 4 | generalErrorMessage: 'Toolset request failed', 5 | apiVersion: 'openai', 6 | pathParameter: 'toolsets', 7 | dynamicSlugs: true, 8 | }); 9 | -------------------------------------------------------------------------------- /libs/modulify-ui/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts", "src/**/*.tsx"], 9 | "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/topicsTooltip.ts: -------------------------------------------------------------------------------- 1 | import { MarketplaceEntitySelectors } from '@/src/ui/selectors'; 2 | import { Tooltip } from '@/src/ui/webElements/tooltip'; 3 | 4 | export class TopicsTooltip extends Tooltip { 5 | public topic = this.getChildElementBySelector( 6 | MarketplaceEntitySelectors.topic, 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /apps/chat/src/utils/auth/timeout-async.ts: -------------------------------------------------------------------------------- 1 | class TimeoutError extends Error { 2 | constructor() { 3 | super('Timeout occurs'); 4 | } 5 | } 6 | 7 | export const timeoutAsync = (t: number) => 8 | new Promise((_, reject) => { 9 | setTimeout(() => { 10 | reject(new TimeoutError()); 11 | }, t); 12 | }); 13 | -------------------------------------------------------------------------------- /libs/visualizer-connector/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/Publish/PublicationControls/view-props.ts: -------------------------------------------------------------------------------- 1 | import { CustomApplicationModel } from '@/src/types/applications'; 2 | import { PromptInfo } from '@/src/types/prompt'; 3 | 4 | import { ConversationInfo } from '@epam/ai-dial-shared'; 5 | 6 | export type TEntity = PromptInfo | ConversationInfo | CustomApplicationModel; 7 | -------------------------------------------------------------------------------- /apps/chat/src/constants/routes.ts: -------------------------------------------------------------------------------- 1 | export enum Routes { 2 | Marketplace = '/marketplace', 3 | Widgets = '/widgets', 4 | SelectedWidget = '/widgets/[slug]', 5 | ToolsetEditor = '/toolset-editor', 6 | AppsEditor = '/apps-editor', 7 | ToolsetSignIn = '/auth/toolset-signin', 8 | Chat = '/', 9 | NotFound = '/404', 10 | } 11 | -------------------------------------------------------------------------------- /apps/chat/src/store/service/service.selectors.ts: -------------------------------------------------------------------------------- 1 | import { RootState } from '@/src/types/store'; 2 | 3 | const rootSelector = (state: RootState) => state.service; 4 | 5 | const selectIsSuccessfullySent = (state: RootState) => 6 | rootSelector(state).isSuccessfullySent; 7 | 8 | export const ServiceSelectors = { selectIsSuccessfullySent }; 9 | -------------------------------------------------------------------------------- /libs/chat-visualizer-connector/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "types": ["node"] 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /libs/shared/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './features'; 2 | export * from './visualizer-connector'; 3 | export * from './common'; 4 | export * from './chat'; 5 | export * from './overlay'; 6 | export * from './message-form-schema'; 7 | export * from './import-export'; 8 | export * from './prompt'; 9 | export * from './toolsets'; 10 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/ApplicationWizard/form.ts: -------------------------------------------------------------------------------- 1 | import { DynamicField } from '@/src/components/Common/Forms/DynamicFormFields'; 2 | 3 | export interface CodeData { 4 | // DEPLOYABLE APP 5 | sources: string; 6 | sourceFiles?: string[]; 7 | runtime: string; 8 | endpoints: DynamicField[]; 9 | env: DynamicField[]; 10 | } 11 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/notFoundSelectors.ts: -------------------------------------------------------------------------------- 1 | export const NotFoundSelectors = { 2 | container: '[data-qa="not-found-container"]', 3 | header: '[data-qa="not-found-header"]', 4 | title: '[data-qa="not-found-title"]', 5 | description: '[data-qa="not-found-description"]', 6 | newConversationButton: '[data-qa="new-conversation-btn"]', 7 | }; 8 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/actions/loginInterface.ts: -------------------------------------------------------------------------------- 1 | import { BaseElement } from '@/src/ui/webElements'; 2 | 3 | export interface LoginInterface { 4 | loginToChatBot( 5 | username: string, 6 | password: string, 7 | options?: { setEntitiesEnvVars: boolean }, 8 | ): Promise>; 9 | 10 | getLoginForm(): BaseElement; 11 | } 12 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/DisableOverlay.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * This component needs to be wrapped with component with position: relative. 3 | * 4 | * Creates transparent overlay in full size of the parent container 5 | */ 6 | export const DisableOverlay = () => ( 7 |
8 | ); 9 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/translation.ts: -------------------------------------------------------------------------------- 1 | import { i18n } from 'next-i18next'; 2 | 3 | import { TranslationOptions } from '@/src/types/translation'; 4 | 5 | export const translate = (text: string, options?: TranslationOptions) => 6 | i18n 7 | ? options 8 | ? i18n.t(text, options) 9 | : (i18n.t(text) as unknown as string) 10 | : text; 11 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/clear-messages-state.ts: -------------------------------------------------------------------------------- 1 | import { Message } from '@epam/ai-dial-shared'; 2 | 3 | export const clearStateForMessages = (messages: Message[]): Message[] => { 4 | return messages.map((message) => ({ 5 | ...message, 6 | custom_content: { 7 | ...message.custom_content, 8 | state: undefined, 9 | }, 10 | })); 11 | }; 12 | -------------------------------------------------------------------------------- /libs/modulify-ui/src/lib/utils/common.ts: -------------------------------------------------------------------------------- 1 | export const isObjectType = ( 2 | valueToCheck: unknown, 3 | propsInObject?: string[], 4 | ) => { 5 | return ( 6 | Object.prototype.toString.call(valueToCheck) === '[object Object]' && 7 | propsInObject?.every( 8 | (prop) => prop in (valueToCheck as Record), 9 | ) 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /apps/chat/src/components/Promptbar/components/PromptDialogs/index.tsx: -------------------------------------------------------------------------------- 1 | import { PromptDeleteDialog } from './PromptDeleteDialog'; 2 | import { PromptMoveToDialog } from './PromptMoveToDialog'; 3 | 4 | export const PromptDialogs: React.FC = () => { 5 | return ( 6 | <> 7 | 8 | 9 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './generatorUtil'; 2 | export * from './dateUtil'; 3 | export * from './fileUtil'; 4 | export * from './modelsUtil'; 5 | export * from './bucketUtil'; 6 | export * from './itemUtil'; 7 | export * from './regexUtil'; 8 | export * from './sortingUtil'; 9 | export * from './userUtil'; 10 | export * from './applicationsUtil'; 11 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/entitySelectors.ts: -------------------------------------------------------------------------------- 1 | export const EntitySelectors = { 2 | entityName: '[data-qa="entity-name"]', 3 | conversation: '[data-qa="conversation"]', 4 | prompt: '[data-qa="prompt"]', 5 | file: '[data-qa="file"]', 6 | application: '[data-qa="application"]', 7 | version: '[data-qa="version"]', 8 | entityInput: '[data-qa="entity-input"]', 9 | }; 10 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/utils/userUtil.ts: -------------------------------------------------------------------------------- 1 | export class UserUtil { 2 | public static getE2EUser(parallelIndex: number) { 3 | return process.env.E2E_USERNAME!.split(',')[parallelIndex]; 4 | } 5 | 6 | public static getE2EUsername(parallelIndex: number) { 7 | const user = UserUtil.getE2EUser(parallelIndex); 8 | return user.substring(0, user.indexOf('@')); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/global.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer components { 6 | .button { 7 | @apply rounded border border-gray-800 bg-gray-300 p-2 text-center hover:border-gray-600 hover:bg-gray-200; 8 | } 9 | details { 10 | cursor: pointer; 11 | } 12 | textarea { 13 | padding: 5px 10px; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/dropdownButtonMenu.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | import { Menu } from '@/src/ui/webElements/menu'; 3 | 4 | export class DropdownButtonMenu extends Menu { 5 | public menuOptions = () => this.getChildElementBySelector(Tags.button); 6 | public menuOption = (option: string) => 7 | this.menuOptions().getElementLocatorByText(option); 8 | } 9 | -------------------------------------------------------------------------------- /apps/chat/src/components/Markdown/MemoizedReactMarkdown.tsx: -------------------------------------------------------------------------------- 1 | import { FC, memo } from 'react'; 2 | import ReactMarkdown, { Options } from 'react-markdown'; 3 | 4 | export const MemoizedReactMarkdown: FC = memo( 5 | ReactMarkdown, 6 | (prevProps, nextProps) => 7 | prevProps.children === nextProps.children && 8 | prevProps.className === nextProps.className, 9 | ); 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | blank_issues_enabled: false 3 | contact_links: 4 | - name: ✏️ Ask a question or get support 5 | url: https://github.com/epam/ai-dial-chat/discussions 6 | about: Ask a question or request support for using DIAL chat 7 | - name: 📝 Talk in Discord 8 | url: https://discord.gg/ukzj9U9tEe 9 | about: Discuss your question in Discord 10 | -------------------------------------------------------------------------------- /apps/chat/src/store/codeEditor/codeEditor.types.ts: -------------------------------------------------------------------------------- 1 | import { UploadStatus } from '@epam/ai-dial-shared'; 2 | 3 | export interface CodeEditorState { 4 | filesContent: { 5 | id: string; 6 | content: string; 7 | modifiedContent: string | undefined; 8 | modified: boolean; 9 | }[]; 10 | fileContentLoadingStatus: UploadStatus; 11 | selectedFileId: string | undefined; 12 | } 13 | -------------------------------------------------------------------------------- /apps/chat/public/locales/en/chat.json: -------------------------------------------------------------------------------- 1 | { 2 | "chat.error.incorrect-selected_model": "Not available agent selected. Please, change the agent to proceed", 3 | "chat.error.agent-not-available": "Agent is not available. Please, {{click}} {{agentId}} to proceed.", 4 | "chat.error.agents-not-available": "Agents are not available. Please, change the agents {{agentId}} and {{agentId}} to proceed." 5 | } 6 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/editSelectors.ts: -------------------------------------------------------------------------------- 1 | import { Attributes, Tags } from '@/src/ui/domData'; 2 | 3 | export const EditSelectors = { 4 | editContainer: '[data-qa="edit-container"]', 5 | editInput: `${Tags.input}[${Attributes.name}="edit-input"]`, 6 | actionsContainer: '[data-qa="actions"]', 7 | confirmEdit: '[data-qa="confirm-edit"]', 8 | cancelEdit: '[data-qa="cancel-edit"]', 9 | }; 10 | -------------------------------------------------------------------------------- /apps/chat-e2e/.env.development: -------------------------------------------------------------------------------- 1 | # E2E_HOST use only for CI 2 | # E2E_HOST="" 3 | # E2E_USERNAME="" # used for Auth0 E2E login 4 | # E2E_PASSWORD="" 5 | # TMS_URL="" 6 | # ISSUE_URL="" 7 | 8 | # Auth0 Configuration for Debug Auth 9 | # AUTH_AUTH0_CLIENT_ID= 10 | # AUTH_AUTH0_HOST= 11 | # AUTH_AUTH0_AUDIENCE= 12 | # AUTH_CONNECTION= 13 | # AUTH_TENANT= 14 | # AUTH0_INTSTATE= 15 | # AUTH_CALLBACK_URL_OVERRIDE 16 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/chatLoader.ts: -------------------------------------------------------------------------------- 1 | import { ToastSelectors } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class ChatLoader extends BaseElement { 6 | constructor(page: Page, parentLocator: Locator) { 7 | super(page, ToastSelectors.chatLoader, parentLocator); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/dropdownCheckboxMenu.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | import { Menu } from '@/src/ui/webElements/menu'; 3 | 4 | export class DropdownCheckboxMenu extends Menu { 5 | public menuOptions = () => this.getChildElementBySelector(Tags.div); 6 | public menuOption = (option: string) => 7 | this.menuOptions().getElementLocatorByText(option).locator(Tags.input); 8 | } 9 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/pages/DialErrorPage.ts: -------------------------------------------------------------------------------- 1 | import { BasePage } from '@/src/ui/pages/basePage'; 2 | import { NotFound } from '@/src/ui/webElements'; 3 | 4 | export class DialErrorPage extends BasePage { 5 | private notFound!: NotFound; 6 | 7 | public getNotFound(): NotFound { 8 | if (!this.notFound) { 9 | this.notFound = new NotFound(this.page); 10 | } 11 | return this.notFound; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityEditor/externalApp/externalAppEditorViewForm.ts: -------------------------------------------------------------------------------- 1 | import { AddExternalAppSettingsFormSelector } from '@/src/ui/selectors'; 2 | import { EntityEditorViewForm } from '@/src/ui/webElements'; 3 | 4 | export class ExternalAppEditorViewForm extends EntityEditorViewForm { 5 | public externalUrl = this.getChildElementBySelector( 6 | AddExternalAppSettingsFormSelector.externalUrl, 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/circle-check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from './baseApiHelper'; 2 | export * from './chatApiHelper'; 3 | export * from './fileApiHelper'; 4 | export * from './iconApiHelper'; 5 | export * from './itemApiHelper'; 6 | export * from './shareApiHelper'; 7 | export * from './publicationApiHelper'; 8 | export * from './applicationApiHelper'; 9 | export * from './modelApiHelper'; 10 | export * from './toolsetApiHelper'; 11 | -------------------------------------------------------------------------------- /apps/chat/src/utils/json.ts: -------------------------------------------------------------------------------- 1 | export const safeParseJSON = ( 2 | jsonData: string | undefined, 3 | errorMessage: string, 4 | logger: { error: (...args: unknown[]) => void }, 5 | ) => { 6 | try { 7 | if (!jsonData) { 8 | return {}; 9 | } 10 | return JSON.parse(jsonData); 11 | } catch (err) { 12 | logger.error(errorMessage, err); 13 | throw Error(`${errorMessage}: ${err}`); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /apps/chat/src/utils/session.ts: -------------------------------------------------------------------------------- 1 | import { Session } from 'next-auth'; 2 | 3 | import { Feature } from '@epam/ai-dial-shared'; 4 | 5 | export const isUserAdmin = (session: Session | null | undefined) => { 6 | return !!session?.user.isAdmin; 7 | }; 8 | 9 | export const canUserUseFeature = ( 10 | session: Session | null | undefined, 11 | feature: Feature, 12 | ) => { 13 | return session?.user?.[feature] ?? true; 14 | }; 15 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import './global.css'; 2 | 3 | export const metadata = { 4 | title: 'Welcome to overlay-sandbox', 5 | description: 'Generated by create-nx-workspace', 6 | }; 7 | 8 | export default function RootLayout({ 9 | children, 10 | }: { 11 | children: React.ReactNode; 12 | }) { 13 | return ( 14 | 15 | {children} 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/common/button.ts: -------------------------------------------------------------------------------- 1 | import { ButtonSelectors } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class Button extends BaseElement { 6 | constructor(page: Page, ariaLabel: string, parentLocator?: Locator) { 7 | super(page, ButtonSelectors.buttonContainer(ariaLabel), parentLocator); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/disabled-all-features-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | const overlayOptions = { 9 | ...commonOverlayProps, 10 | enabledFeatures: [], 11 | }; 12 | 13 | export default function Index() { 14 | return ; 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Workflow 2 | 3 | on: 4 | push: 5 | branches: [development, release-*] 6 | 7 | concurrency: 8 | group: ${{ github.workflow }}-${{ github.ref }} 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | release: 13 | uses: epam/ai-dial-ci/.github/workflows/node_release.yml@3.0.0 14 | secrets: inherit 15 | with: 16 | node-version: 24 17 | maximize-build-space: true 18 | -------------------------------------------------------------------------------- /apps/chat/src/store/hooks.ts: -------------------------------------------------------------------------------- 1 | import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; 2 | 3 | import { RootState } from '@/src/types/store'; 4 | 5 | import type { AppDispatch } from './'; 6 | 7 | // Use throughout your app instead of plain useDispatch and useSelector 8 | export const useAppDispatch: () => AppDispatch = useDispatch; 9 | export const useAppSelector: TypedUseSelectorHook = useSelector; 10 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/refresh-cw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/types/translation.ts: -------------------------------------------------------------------------------- 1 | export enum Translation { 2 | Chat = 'chat', 3 | Common = 'common', 4 | Markdown = 'markdown', 5 | PromptBar = 'promptbar', 6 | Settings = 'settings', 7 | SideBar = 'sidebar', 8 | Files = 'files', 9 | Marketplace = 'marketplace', 10 | Header = 'header', 11 | Errors = 'errors', 12 | } 13 | 14 | export type TranslationOptions = Record & { 15 | ns?: Translation; 16 | }; 17 | -------------------------------------------------------------------------------- /apps/chat/src/hooks/useResizeObserver.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | 3 | export const useResizeObserver = ( 4 | target: Element | null, 5 | callback: ResizeObserverCallback, 6 | ) => { 7 | useEffect(() => { 8 | const observer = new ResizeObserver(callback); 9 | 10 | if (target) { 11 | observer.observe(target); 12 | } 13 | 14 | return () => observer.disconnect(); 15 | }, [callback, target]); 16 | }; 17 | -------------------------------------------------------------------------------- /.github/workflows/cleanup-untagged-images.yml: -------------------------------------------------------------------------------- 1 | name: Cleanup untagged images 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | jobs: 8 | clean: 9 | name: Delete untagged images 10 | runs-on: ubuntu-latest 11 | permissions: 12 | packages: write 13 | steps: 14 | - uses: dataaxiom/ghcr-cleanup-action@cd0cdb900b5dbf3a6f2cc869f0dbb0b8211f50c4 # v1.0.16 15 | with: 16 | delete-untagged: true 17 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: PR Workflow 2 | 3 | on: 4 | pull_request: 5 | branches: [development, release-*] 6 | 7 | concurrency: 8 | group: ${{ github.workflow }}-${{ github.event.pull_request.number }} 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | run_tests: 13 | uses: epam/ai-dial-ci/.github/workflows/node_pr.yml@3.0.0 14 | secrets: inherit 15 | with: 16 | node-version: 24 17 | maximize-build-space: true 18 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/domData/tags.ts: -------------------------------------------------------------------------------- 1 | export enum Tags { 2 | span = 'span', 3 | textarea = 'textarea', 4 | button = 'button', 5 | input = 'input', 6 | div = 'div', 7 | svg = 'svg', 8 | img = 'img', 9 | a = 'a', 10 | table = 'table', 11 | thead = 'thead', 12 | th = 'th', 13 | tbody = 'tbody', 14 | td = 'td', 15 | html = 'html', 16 | label = 'label', 17 | dialog = 'dialog', 18 | p = 'p', 19 | section = 'section', 20 | } 21 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/overlay/dialog.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | import { BaseElement } from '@/src/ui/webElements'; 3 | import { Page } from '@playwright/test'; 4 | 5 | export class Dialog extends BaseElement { 6 | constructor(page: Page) { 7 | super(page, Tags.dialog); 8 | } 9 | 10 | public closeButton = this.getChildElementBySelector(Tags.button); 11 | public content = this.getChildElementBySelector(Tags.p); 12 | } 13 | -------------------------------------------------------------------------------- /apps/chat/src/components/Header/User/User.tsx: -------------------------------------------------------------------------------- 1 | import { ProfileButton } from './ProfileButton'; 2 | import { UserDesktop } from './UserDesktop'; 3 | 4 | export const User = () => { 5 | return ( 6 | <> 7 |
8 | 9 |
10 | 11 |
12 | 13 |
14 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /apps/chat/src/components/Marketplace/Rating/RatingProgressBar.tsx: -------------------------------------------------------------------------------- 1 | interface Props { 2 | total: number; 3 | count: number; 4 | } 5 | 6 | export const RatingProgressBar = ({ total, count }: Props) => { 7 | return ( 8 |
9 |
13 |
14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/epics-helpers/application.epic-helpers.ts: -------------------------------------------------------------------------------- 1 | import { NextRouter } from 'next/router'; 2 | 3 | import { Observable, from, mergeMap } from 'rxjs'; 4 | 5 | import { AppAction } from '@/src/types/store'; 6 | 7 | export const navigateAndThen = ( 8 | router: NextRouter, 9 | to: Parameters[0], 10 | after$: Observable, 11 | ) => { 12 | return from(router.push(to, undefined)).pipe(mergeMap(() => after$)); 13 | }; 14 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import './global.css'; 2 | 3 | import React from 'react'; 4 | 5 | export const metadata = { 6 | title: 'Custom Viewer Test Page', 7 | description: 'This is a test page for the custom viewer.', 8 | }; 9 | 10 | export default function RootLayout({ 11 | children, 12 | }: { 13 | children: React.ReactNode; 14 | }) { 15 | return ( 16 | 17 | {children} 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/refresh-cw-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/BlinkingCursor.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react'; 2 | 3 | import { modelCursorSign } from '@/src/constants/chat'; 4 | 5 | interface BlinkingCursorProps { 6 | isShowing: boolean; 7 | } 8 | 9 | export const BlinkingCursor: FC = ({ isShowing }) => { 10 | return isShowing ? ( 11 | 12 | {modelCursorSign} 13 | 14 | ) : null; 15 | }; 16 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: 'all', 3 | singleQuote: true, 4 | plugins: [ 5 | '@trivago/prettier-plugin-sort-imports', 6 | 'prettier-plugin-tailwindcss', 7 | ], 8 | tailwindFunctions: ['classnames', 'classNames'], 9 | importOrder: [ 10 | '', 11 | '^[./]', // Other imports 12 | '.*', // Any uncaught imports 13 | ], 14 | importOrderSeparation: true, 15 | importOrderSortSpecifiers: true, 16 | }; 17 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/messageTemplateModalAssertion.ts: -------------------------------------------------------------------------------- 1 | import { BaseAssertion } from '@/src/assertions/base/baseAssertion'; 2 | import { MessageTemplateModal } from '@/src/ui/webElements'; 3 | 4 | export class MessageTemplateModalAssertion extends BaseAssertion { 5 | readonly messageTemplateModal: MessageTemplateModal; 6 | 7 | constructor(messageTemplateModal: MessageTemplateModal) { 8 | super(); 9 | this.messageTemplateModal = messageTemplateModal; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.github/workflows/pr-title-check.yml: -------------------------------------------------------------------------------- 1 | name: "Validate PR title" 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - reopened 9 | 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.event.pull_request.number }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | pr-title-check: 16 | uses: epam/ai-dial-ci/.github/workflows/pr-title-check.yml@3.0.0 17 | secrets: 18 | ACTIONS_BOT_TOKEN: ${{ secrets.ACTIONS_BOT_TOKEN }} 19 | -------------------------------------------------------------------------------- /apps/chat/src/hooks/useLogout.ts: -------------------------------------------------------------------------------- 1 | import { signIn, useSession } from 'next-auth/react'; 2 | import { useCallback } from 'react'; 3 | 4 | import { customSignOut } from '@/src/utils/auth/signOut'; 5 | 6 | export const useLogout = () => { 7 | const { data: session } = useSession(); 8 | const handleLogout = useCallback(() => { 9 | session ? customSignOut() : signIn('azure-ad', { redirect: true }); 10 | }, [session]); 11 | return { 12 | session, 13 | handleLogout, 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-only-header-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [Feature.Header], 13 | }; 14 | 15 | export default function Index() { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat/src/constants/folders.ts: -------------------------------------------------------------------------------- 1 | export const MAX_CONVERSATION_AND_PROMPT_FOLDERS_DEPTH = 3; 2 | 3 | export const FOLDER_ATTACHMENT_CONTENT_TYPE = 4 | 'application/vnd.dial.metadata+json'; 5 | 6 | export const PROMPT_VARIABLE_REGEX_TEST = /{{([^|]+?)(\|.*?)?}}/; 7 | export const PROMPT_VARIABLE_REGEX_GLOBAL = new RegExp( 8 | PROMPT_VARIABLE_REGEX_TEST, 9 | 'g', 10 | ); 11 | 12 | export const METADATA_PREFIX = 'metadata/'; 13 | 14 | export const TEMPORARY_FOLDER_ROOT_ID = 'temporary/temporaryBucket'; 15 | -------------------------------------------------------------------------------- /apps/chat/src/store/folders/folders.selectors.ts: -------------------------------------------------------------------------------- 1 | import { RootState } from '@/src/types/store'; 2 | 3 | const rootSelector = (state: RootState) => state.folders; 4 | 5 | const selectTemporaryFolders = (state: RootState) => 6 | rootSelector(state).temporaryFolders; 7 | 8 | const selectNewAddedTemporaryFolderId = (state: RootState) => 9 | rootSelector(state).newAddedTemporaryFolderId; 10 | 11 | export const FoldersSelectors = { 12 | selectTemporaryFolders, 13 | selectNewAddedTemporaryFolderId, 14 | }; 15 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/style-helpers.ts: -------------------------------------------------------------------------------- 1 | import { FocusEvent } from 'react'; 2 | 3 | import kebabCase from 'lodash-es/kebabCase'; 4 | 5 | export const onBlur = (e: FocusEvent) => { 6 | e.target.classList.add('submitted', 'input-invalid'); 7 | }; 8 | 9 | export const getTopicColors = (topic: string) => ({ 10 | backgroundColor: `var(--bg-topic-${kebabCase(topic)}, var(--bg-topic-default, #5C8DEA2B))`, 11 | borderColor: `var(--stroke-topic-${kebabCase(topic)}, var(--stroke-topic-default, #5C8DEA))`, 12 | }); 13 | -------------------------------------------------------------------------------- /apps/chat/src/components/Marketplace/MarketplaceEntitiesList/view-props.ts: -------------------------------------------------------------------------------- 1 | export interface MarketplaceEntitiesListProps { 2 | entities: T[]; 3 | suggestedResults: T[]; 4 | separator: string; 5 | onCardClick: (entity: T) => void; 6 | onBookmarkClick?: (entity: T) => void; 7 | onSelectVersion?: (entity: T) => void; 8 | } 9 | 10 | export interface MarketplaceEntitiesListWrapperRef { 11 | parentRef: React.RefObject; 12 | suggestedRowRef: React.RefObject; 13 | } 14 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-only-header-footer-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [Feature.Header, Feature.Footer], 13 | }; 14 | 15 | export default function Index() { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /libs/shared/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epam/ai-dial-shared", 3 | "description": "Shared elements that support developing DIAL", 4 | "homepage": "https://dialx.ai", 5 | "version": "0.0.1", 6 | "dependencies": {}, 7 | "type": "module", 8 | "bugs": { 9 | "url": "https://github.com/epam/ai-dial-chat/issues" 10 | }, 11 | "license": "Apache-2.0", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/epam/ai-dial-chat.git", 15 | "directory": "libs/shared" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libs/shared/src/types/json-schema.ts: -------------------------------------------------------------------------------- 1 | export enum JSONSchemaPropertyType { 2 | array = 'array', 3 | number = 'number', 4 | type = 'integer', 5 | string = 'string', 6 | boolean = 'boolean', 7 | } 8 | 9 | export interface JSONSchemaPropertyBase { 10 | type: JSONSchemaPropertyType; 11 | 12 | title?: string; 13 | description?: string; 14 | } 15 | 16 | export interface JSONSchemaBase { 17 | type: 'object'; 18 | properties: Record; 19 | required?: string[]; 20 | } 21 | -------------------------------------------------------------------------------- /libs/shared/src/utils/styleUtils.ts: -------------------------------------------------------------------------------- 1 | import { Styles } from '../types'; 2 | 3 | /** 4 | * Add styles to the html element 5 | * @param htmlElement {HTMLElement} element for which styles should be added 6 | * @param styles {Styles} styles that should be added to element 7 | */ 8 | export function setStyles(htmlElement: HTMLElement, styles: Styles): void { 9 | for (const key in styles) { 10 | const value = styles[key]; 11 | 12 | if (!value) continue; 13 | 14 | htmlElement.style[key] = value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-hide-user-settings-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [Feature.HideUserSettings, Feature.Header], 13 | }; 14 | 15 | export default function Index() { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/modalError.ts: -------------------------------------------------------------------------------- 1 | import { ErrorLabelSelectors } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class ModalError extends BaseElement { 6 | constructor(page: Page, parentLocator?: Locator) { 7 | super(page, ErrorLabelSelectors.errorContainer, parentLocator); 8 | } 9 | 10 | public errorMessage = this.getChildElementBySelector( 11 | ErrorLabelSelectors.errorText, 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/ReplaceConfirmationModal/ReplaceRowContainer.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | 3 | import classNames from 'classnames'; 4 | 5 | interface FeatureContainerProps { 6 | children: ReactNode | ReactNode[]; 7 | className?: string; 8 | } 9 | 10 | export const FeatureContainer = ({ 11 | children, 12 | className, 13 | }: FeatureContainerProps) => ( 14 | 17 | {children} 18 | 19 | ); 20 | -------------------------------------------------------------------------------- /apps/chat/src/store/applicationTypeSchemas/applicationTypeSchemas.types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApiDetailedApplicationTypeSchema, 3 | ApplicationTypeSchema, 4 | } from '@/src/types/application-type-schema'; 5 | 6 | import { UploadStatus } from '@epam/ai-dial-shared'; 7 | 8 | export interface ApplicationTypesSchemasState { 9 | schemasLoading: UploadStatus; 10 | schemas: ApplicationTypeSchema[]; 11 | detailedApplicationTypeSchema: ApiDetailedApplicationTypeSchema | null; 12 | detailedApplicationTypeSchemaLoading: UploadStatus; 13 | } 14 | -------------------------------------------------------------------------------- /apps/chat/src/store/migration/migration.types.ts: -------------------------------------------------------------------------------- 1 | import { Conversation } from '@/src/types/chat'; 2 | import { Prompt } from '@/src/types/prompt'; 3 | 4 | export interface MigrationState { 5 | initialized: boolean; 6 | conversationsToMigrateCount: number; 7 | migratedConversationsCount: number; 8 | failedMigratedConversations: Conversation[]; 9 | isChatsBackedUp: boolean; 10 | promptsToMigrateCount: number; 11 | migratedPromptsCount: number; 12 | failedMigratedPrompts: Prompt[]; 13 | isPromptsBackedUp: boolean; 14 | } 15 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/tooltip.ts: -------------------------------------------------------------------------------- 1 | import { TooltipSelector } from '@/src/ui/selectors/dialogSelectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { Page } from '@playwright/test'; 4 | 5 | export class Tooltip extends BaseElement { 6 | constructor(page: Page) { 7 | super(page, TooltipSelector.tooltip); 8 | } 9 | 10 | public tooltipIcon = this.getElementIcon(this.getElementLocator()); 11 | 12 | public async getContent() { 13 | return this.getElementInnerContent(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat/src/components/Marketplace/MarketplaceEntityTopic.tsx: -------------------------------------------------------------------------------- 1 | import { getTopicColors } from '@/src/utils/app/style-helpers'; 2 | 3 | interface Props { 4 | topic: string; 5 | } 6 | 7 | export const MarketplaceEntityTopic = ({ topic }: Props) => { 8 | return ( 9 | 14 | {topic} 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-hide-empty-change-agent-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [Feature.HideEmptyChatChangeAgent, Feature.Header], 13 | }; 14 | 15 | export default function Index() { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /libs/overlay/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "forceConsistentCasingInFileNames": true, 5 | "strict": true, 6 | "noImplicitOverride": true, 7 | "noPropertyAccessFromIndexSignature": true, 8 | "noImplicitReturns": true, 9 | "noFallthroughCasesInSwitch": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.lib.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityEditor/base/entitySettings/entityEditorViewForm.ts: -------------------------------------------------------------------------------- 1 | import { AddEntitySettingsFormSelector } from '@/src/ui/selectors'; 2 | import { EntityEditorForm } from '@/src/ui/webElements'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export abstract class EntityEditorViewForm extends EntityEditorForm { 6 | constructor(page: Page, parentLocator: Locator) { 7 | super( 8 | page, 9 | AddEntitySettingsFormSelector.entityViewFormContainer, 10 | parentLocator, 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/rotate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Plotly/PlotlyStringDataRenderer.tsx: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react'; 2 | import { PlotParams } from 'react-plotly.js'; 3 | 4 | import { PlotlyComponent } from './Plotly'; 5 | 6 | interface Props { 7 | plotlyStringData: string; 8 | } 9 | 10 | export function PlotlyStringDataRenderer({ plotlyStringData }: Props) { 11 | const plotlyData = useMemo( 12 | () => JSON.parse(plotlyStringData) as PlotParams, 13 | [plotlyStringData], 14 | ); 15 | 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-only-header-conversations-section-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [Feature.Header, Feature.ConversationsSection], 13 | }; 14 | 15 | export default function Index() { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/manageAttachmentFoldersAssertion.ts: -------------------------------------------------------------------------------- 1 | import { FolderAssertion } from '@/src/assertions/folderAssertion'; 2 | import { AttachFilesModal, FileModalSection } from '@/src/ui/webElements'; 3 | import { Folders } from '@/src/ui/webElements/entityTree'; 4 | 5 | export class ManageAttachmentFoldersAssertion extends FolderAssertion { 6 | constructor(attachFilesModal: AttachFilesModal, section: FileModalSection) { 7 | const folderSection = attachFilesModal.getFolderTree(section); 8 | super(folderSection); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/publication/publishFolderFiles.ts: -------------------------------------------------------------------------------- 1 | import { EntitySelectors, PublishingTreeSelectors } from '@/src/ui/selectors'; 2 | import { PublishFolder } from '@/src/ui/webElements/entityTree'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class PublishFolderFiles extends PublishFolder { 6 | constructor(page: Page, parentLocator: Locator) { 7 | super( 8 | page, 9 | parentLocator, 10 | PublishingTreeSelectors.filesTree, 11 | EntitySelectors.file, 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/chat/src/types/themes.ts: -------------------------------------------------------------------------------- 1 | export interface Theme { 2 | displayName: string; 3 | colors: Record; 4 | topicColors: Record; 5 | authColors: Record; 6 | banners?: Record; 7 | 'code-editor-theme'?: string; 8 | 'app-logo': string; 9 | 'font-family'?: string; 10 | 'font-codeblock'?: string; 11 | id: string; 12 | } 13 | 14 | export type ThemesImages = Record; 15 | 16 | export interface ThemesConfig { 17 | themes: Theme[]; 18 | images: ThemesImages; 19 | } 20 | -------------------------------------------------------------------------------- /trivy.yaml: -------------------------------------------------------------------------------- 1 | # Trivy configuration file 2 | # https://aquasecurity.github.io/trivy/latest/docs/references/configuration/config-file/ 3 | # Can be deleted after public ecr mirror will be added by default 4 | db: 5 | no-progress: true 6 | repository: 7 | - ghcr.io/aquasecurity/trivy-db:2 8 | - public.ecr.aws/aquasecurity/trivy-db:2 9 | java-repository: 10 | - ghcr.io/aquasecurity/trivy-java-db:1 11 | - public.ecr.aws/aquasecurity/trivy-java-db:1 12 | misconfiguration: 13 | checks-bundle-repository: public.ecr.aws/aquasecurity/trivy-checks 14 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/importExportLoader.ts: -------------------------------------------------------------------------------- 1 | import { ImportExportSelectors } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class ImportExportLoader extends BaseElement { 6 | constructor(page: Page, parentLocator: Locator) { 7 | super(page, ImportExportSelectors.importExportLoader, parentLocator); 8 | } 9 | 10 | public stopLoading = this.getChildElementBySelector( 11 | ImportExportSelectors.stopLoading, 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/chat/src/components/Marketplace/MarketplaceEditorView/marketplaceEditorViewContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from 'react'; 2 | 3 | import { PreviewMode } from '@/src/types/marketplace'; 4 | 5 | export const MarketplaceEditorViewContext = createContext<{ 6 | previewMode: PreviewMode; 7 | changePreviewMode: (mode: PreviewMode) => void; 8 | }>({ 9 | previewMode: PreviewMode.closed, 10 | changePreviewMode: () => undefined, 11 | }); 12 | 13 | export const useMarketplaceEditorView = () => 14 | useContext(MarketplaceEditorViewContext); 15 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "plugin:@nx/react-typescript", 4 | "next", 5 | "next/core-web-vitals", 6 | "../../.eslintrc.json" 7 | ], 8 | "ignorePatterns": ["!**/*", ".next/**/*"], 9 | "overrides": [ 10 | { 11 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 12 | "extends": ["../../.eslintrc.json"], 13 | "rules": { 14 | "@next/next/no-html-link-for-pages": [ 15 | "error", 16 | "apps/overlay-sandbox/pages" 17 | ] 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /libs/overlay/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epam/ai-dial-overlay", 3 | "description": "Package for opening dial in overlay", 4 | "homepage": "https://dialx.ai", 5 | "version": "0.4.3", 6 | "dependencies": { 7 | "@epam/ai-dial-shared": "*" 8 | }, 9 | "type": "module", 10 | "bugs": { 11 | "url": "https://github.com/epam/ai-dial-chat/issues" 12 | }, 13 | "license": "Apache-2.0", 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/epam/ai-dial-chat.git", 17 | "directory": "libs/overlay" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/visualizer-connector/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "forceConsistentCasingInFileNames": true, 5 | "strict": true, 6 | "noImplicitOverride": true, 7 | "noPropertyAccessFromIndexSignature": true, 8 | "noImplicitReturns": true, 9 | "noFallthroughCasesInSwitch": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.lib.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/publication/publishFolderPrompts.ts: -------------------------------------------------------------------------------- 1 | import { EntitySelectors, PublishingTreeSelectors } from '@/src/ui/selectors'; 2 | import { PublishFolder } from '@/src/ui/webElements/entityTree'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class PublishFolderPrompts extends PublishFolder { 6 | constructor(page: Page, parentLocator: Locator) { 7 | super( 8 | page, 9 | parentLocator, 10 | PublishingTreeSelectors.promptsTree, 11 | EntitySelectors.prompt, 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "plugin:@nx/react-typescript", 4 | "next", 5 | "next/core-web-vitals", 6 | "../../.eslintrc.json" 7 | ], 8 | "ignorePatterns": ["!**/*", ".next/**/*"], 9 | "overrides": [ 10 | { 11 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], 12 | "extends": ["../../.eslintrc.json"], 13 | "rules": { 14 | "@next/next/no-html-link-for-pages": [ 15 | "error", 16 | "apps/custom-viewer-test/pages" 17 | ] 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /libs/chat-visualizer-connector/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "forceConsistentCasingInFileNames": true, 5 | "strict": true, 6 | "noImplicitOverride": true, 7 | "noPropertyAccessFromIndexSignature": true, 8 | "noImplicitReturns": true, 9 | "noFallthroughCasesInSwitch": true 10 | }, 11 | "files": [], 12 | "include": [], 13 | "references": [ 14 | { 15 | "path": "./tsconfig.lib.json" 16 | }, 17 | { 18 | "path": "./tsconfig.spec.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/sidebar/sharedFolderConversations.ts: -------------------------------------------------------------------------------- 1 | import { ChatBarSelectors, EntitySelectors } from '../../../selectors'; 2 | 3 | import { Folders } from '@/src/ui/webElements/entityTree/folders'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class SharedFolderConversations extends Folders { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | ChatBarSelectors.sharedWithMeChats(), 12 | EntitySelectors.conversation, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/search-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /libs/modulify-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epam/ai-dial-modulify-ui", 3 | "description": "Modulify Toolkit (UI) for turning a monolith-like project into a modular one", 4 | "homepage": "https://dialx.ai", 5 | "version": "0.0.1", 6 | "dependencies": {}, 7 | "type": "module", 8 | "bugs": { 9 | "url": "https://github.com/epam/ai-dial-chat/issues" 10 | }, 11 | "license": "Apache-2.0", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/epam/ai-dial-chat.git", 15 | "directory": "libs/modulify-ui" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/pages/loginPage.ts: -------------------------------------------------------------------------------- 1 | import { BaseElement } from '../webElements'; 2 | import { BasePage } from './basePage'; 3 | 4 | import { AuthProvider } from '@/src/testData'; 5 | import { Auth0Selectors } from '@/src/ui/selectors'; 6 | 7 | export class LoginPage extends BasePage { 8 | public auth0SignInButton = new BaseElement( 9 | this.page, 10 | Auth0Selectors.ssoSignIn(AuthProvider.auth0), 11 | ); 12 | 13 | public keycloakSignInButton = new BaseElement( 14 | this.page, 15 | Auth0Selectors.ssoSignIn(AuthProvider.keycloak), 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/sidebar/promptsTree.ts: -------------------------------------------------------------------------------- 1 | import { EntitySelectors, PromptBarSelectors } from '../../../selectors'; 2 | 3 | import { SideBarEntitiesTree } from '@/src/ui/webElements/entityTree/sidebar/sideBarEntitiesTree'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class PromptsTree extends SideBarEntitiesTree { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | PromptBarSelectors.prompts, 12 | EntitySelectors.prompt, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /libs/shared/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.lib.json" 17 | }, 18 | { 19 | "path": "./tsconfig.spec.json" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/keyboard.ts: -------------------------------------------------------------------------------- 1 | const isMac = process.platform === 'darwin'; 2 | 3 | export const keys = { 4 | enter: 'Enter', 5 | ctrlPlusA: isMac ? 'Meta+A' : 'Control+A', 6 | ctrlPlusC: isMac ? 'Meta+C' : 'Control+C', 7 | ctrlPlusV: isMac ? 'Meta+V' : 'Control+V', 8 | shiftPlusEnter: 'Shift+Enter', 9 | home: 'Home', 10 | end: 'End', 11 | space: 'Space', 12 | arrowRight: 'ArrowRight', 13 | arrowLeft: 'ArrowLeft', 14 | arrowUp: 'ArrowUp', 15 | arrowDown: 'ArrowDown', 16 | delete: 'Delete', 17 | backspace: 'Backspace', 18 | escape: 'Escape', 19 | }; 20 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/errors.ts: -------------------------------------------------------------------------------- 1 | import { errorsMessages } from '@/src/constants/errors'; 2 | 3 | export const getEntityNameError = ( 4 | isNameInvalid: boolean, 5 | isPathInvalid: boolean, 6 | isExternal: boolean, 7 | ) => { 8 | if (isNameInvalid) { 9 | return isExternal 10 | ? errorsMessages.entityNameInvalidExternal 11 | : errorsMessages.entityNameInvalid; 12 | } else if (isPathInvalid) { 13 | return isExternal 14 | ? errorsMessages.entityPathInvalidExternal 15 | : errorsMessages.entityPathInvalid; 16 | } 17 | return ''; 18 | }; 19 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/sidebar/organizationPromptsTree.ts: -------------------------------------------------------------------------------- 1 | import { EntitySelectors, PromptBarSelectors } from '../../../selectors'; 2 | 3 | import { SideBarEntitiesTree } from '@/src/ui/webElements/entityTree'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class OrganizationPromptsTree extends SideBarEntitiesTree { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | PromptBarSelectors.organizationPrompts(), 12 | EntitySelectors.prompt, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/publication/publishFolderConversations.ts: -------------------------------------------------------------------------------- 1 | import { EntitySelectors, PublishingTreeSelectors } from '@/src/ui/selectors'; 2 | import { PublishFolder } from '@/src/ui/webElements/entityTree'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class PublishFolderConversations extends PublishFolder { 6 | constructor(page: Page, parentLocator: Locator) { 7 | super( 8 | page, 9 | parentLocator, 10 | PublishingTreeSelectors.conversationsTree, 11 | EntitySelectors.conversation, 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/insert-prompt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/hooks/useScreenState.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | import { getScreenState } from '@/src/utils/app/mobile'; 4 | 5 | export const useScreenState = () => { 6 | const [screenState, setScreenState] = useState(getScreenState()); 7 | 8 | useEffect(() => { 9 | const handleResize = () => setScreenState(getScreenState()); 10 | const resizeObserver = new ResizeObserver(handleResize); 11 | 12 | resizeObserver.observe(document.body); 13 | 14 | return () => resizeObserver.disconnect(); 15 | }, []); 16 | 17 | return screenState; 18 | }; 19 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/README.md: -------------------------------------------------------------------------------- 1 | # Overlay sandbox 2 | 3 | Overlay sandbox contains examples of applications based on overlay library. 4 | 5 | Before starting apps, need to specify the `NEXT_PUBLIC_OVERLAY_HOST` env variable that refers to the DIAL chat host launched in overlay mode and the `NEXT_PUBLIC_OVERLAY_USER_BUCKET` variable that corresponds to the user bucket suppose to use the sandbox. 6 | See [DIAL Overlay](https://github.com/epam/ai-dial-chat/blob/development/libs/overlay/README.md) for details. 7 | 8 | Run the following command to start sandbox: `nx run overlay-sandbox:"serve:sandbox"` 9 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/sidebar/sharedWithMeConversationsTree.ts: -------------------------------------------------------------------------------- 1 | import { ChatBarSelectors, EntitySelectors } from '../../../selectors'; 2 | 3 | import { SideBarEntitiesTree } from '@/src/ui/webElements/entityTree'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class SharedWithMeConversationsTree extends SideBarEntitiesTree { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | ChatBarSelectors.sharedWithMeChats(), 12 | EntitySelectors.conversation, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat/src/types/modal.ts: -------------------------------------------------------------------------------- 1 | import { FolderInterface } from '@/src/types/folder'; 2 | import { SharingType } from '@/src/types/share'; 3 | 4 | import { PublishActions, ShareEntity } from '@epam/ai-dial-shared'; 5 | 6 | export enum ModalState { 7 | CLOSED = 'CLOSED', 8 | LOADING = 'LOADING', 9 | OPENED = 'OPENED', 10 | } 11 | 12 | export type OnItemEvent = (actionOption: string, entityId: unknown) => void; 13 | 14 | export interface PublicationFolderPayload { 15 | entity: FolderInterface; 16 | entities: ShareEntity[]; 17 | type: SharingType; 18 | action: PublishActions; 19 | } 20 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/tokenizer.ts: -------------------------------------------------------------------------------- 1 | import { Tiktoken, TiktokenEncoding, get_encoding } from 'tiktoken'; 2 | 3 | const encodingCache = new Map(); 4 | 5 | if (import.meta.hot) { 6 | import.meta.hot.dispose(() => { 7 | encodingCache.forEach((encoding) => encoding.free()); 8 | encodingCache.clear(); 9 | }); 10 | } 11 | 12 | export const getOrCreateEncoding = (encoding: TiktokenEncoding): Tiktoken => { 13 | if (!encodingCache.has(encoding)) { 14 | encodingCache.set(encoding, get_encoding(encoding)); 15 | } 16 | return encodingCache.get(encoding)!; 17 | }; 18 | -------------------------------------------------------------------------------- /apps/chat/src/utils/auth/auth-pages.ts: -------------------------------------------------------------------------------- 1 | import { PagesOptions } from 'next-auth'; 2 | 3 | export const pages: Partial = { 4 | // Put here your custom pages for authentication, 5 | // which will be used by next-auth instead of the default ones 6 | // https://authjs.dev/getting-started/session-management/custom-pages 7 | // ------------------------------------------------------------------ 8 | signIn: '/auth/signin', 9 | // signOut: '/auth/signout', 10 | // error: '/auth/error', 11 | // verifyRequest: '/auth/verify-request', 12 | // newUser: '/auth/new-user', 13 | }; 14 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/edit-last-assistant-message/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.EditLastAssistantContent, 14 | Feature.Header, 15 | Feature.ConversationsSection, 16 | ], 17 | }; 18 | 19 | export default function Index() { 20 | return ; 21 | } 22 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredPrompts.ts: -------------------------------------------------------------------------------- 1 | import { ApproveRequiredEntitiesTree } from './approveRequiredEntitiesTree'; 2 | 3 | import { EntitySelectors, PromptBarSelectors } from '@/src/ui/selectors'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class ApproveRequiredPrompts extends ApproveRequiredEntitiesTree { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | PromptBarSelectors.approveRequiredPrompts(), 12 | EntitySelectors.prompt, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/attachments.ts: -------------------------------------------------------------------------------- 1 | import { isAbsoluteUrl } from '@/src/utils/app/file'; 2 | 3 | import { Attachment } from '@epam/ai-dial-shared'; 4 | 5 | export const getMappedAttachmentUrl = (url: string | undefined) => { 6 | if (!url) { 7 | return undefined; 8 | } 9 | return isAbsoluteUrl(url) ? url : `/api/${url}`; 10 | }; 11 | 12 | export const getMappedAttachment = (attachment: Attachment): Attachment => { 13 | return { 14 | ...attachment, 15 | url: getMappedAttachmentUrl(attachment.url), 16 | reference_url: getMappedAttachmentUrl(attachment.url), 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/disabled-top-chat-info-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.TopClearConversation, 14 | Feature.TopChatInfo, 15 | Feature.TopChatModelSettings, 16 | ], 17 | }; 18 | 19 | export default function Index() { 20 | return ; 21 | } 22 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-disallow-change-agent-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.TopSettings, 14 | Feature.TopChatInfo, 15 | Feature.DisallowChangeAgent, 16 | ], 17 | }; 18 | 19 | export default function Index() { 20 | return ; 21 | } 22 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/sidebar/organizationConversationsTree.ts: -------------------------------------------------------------------------------- 1 | import { ChatBarSelectors, EntitySelectors } from '../../../selectors'; 2 | 3 | import { SideBarEntitiesTree } from '@/src/ui/webElements/entityTree'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class OrganizationConversationsTree extends SideBarEntitiesTree { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | ChatBarSelectors.organizationConversations(), 12 | EntitySelectors.conversation, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-hide-top-context-menu-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.TopSettings, 14 | Feature.ConversationsSection, 15 | Feature.HideTopContextMenu, 16 | ], 17 | }; 18 | 19 | export default function Index() { 20 | return ; 21 | } 22 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chatSelectors'; 2 | export * from './loginSelectors'; 3 | export * from './sideBarSelectors'; 4 | export * from './dialogSelectors'; 5 | export * from './headerSelectors'; 6 | export * from './iconSelectors'; 7 | export * from './menuSelectors'; 8 | export * from './fileSelectors'; 9 | export * from './editSelectors'; 10 | export * from './folderSelectors'; 11 | export * from './overlaySelectors'; 12 | export * from './marketplaceSelectors'; 13 | export { EntitySelectors } from '@/src/ui/selectors/entitySelectors'; 14 | export * from './commonSelectors'; 15 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/publication/publishApplicationsTree.ts: -------------------------------------------------------------------------------- 1 | import { EntitySelectors, PublishingTreeSelectors } from '../../../selectors'; 2 | 3 | import { PublishEntitiesTree } from '@/src/ui/webElements/entityTree/publishEntitiesTree'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class PublishApplicationsTree extends PublishEntitiesTree { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | PublishingTreeSelectors.appsTree, 12 | EntitySelectors.application, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/sidebar/sharedWithMePromptsTree.ts: -------------------------------------------------------------------------------- 1 | import { EntitySelectors, PromptBarSelectors } from '../../../selectors'; 2 | 3 | import { SideBarEntitiesTree } from '@/src/ui/webElements/entityTree/sidebar/sideBarEntitiesTree'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class SharedWithMePromptsTree extends SideBarEntitiesTree { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | PromptBarSelectors.sharedWithMePrompts(), 12 | EntitySelectors.prompt, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/keyboard.ts: -------------------------------------------------------------------------------- 1 | import { KeyboardEvent as ReactKeyboardEvent } from 'react'; 2 | 3 | import { EnterType } from '@/src/types/settings'; 4 | 5 | import { isMacOs, isMobile } from './mobile'; 6 | 7 | export const allowEnterClick = ( 8 | e: KeyboardEvent | ReactKeyboardEvent, 9 | enterType: EnterType, 10 | ) => { 11 | if (e.key !== 'Enter' || isMobile() || e.shiftKey || e.altKey) { 12 | return false; 13 | } 14 | if (enterType !== EnterType.CtrlEnter) { 15 | return !e.metaKey && !e.ctrlKey; 16 | } 17 | return isMacOs ? e.metaKey : e.ctrlKey && !e.metaKey; 18 | }; 19 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-only-footer-links-attachments-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.ReportAnIssue, 14 | Feature.RequestApiKey, 15 | Feature.AttachmentsManager, 16 | ], 17 | }; 18 | 19 | export default function Index() { 20 | return ; 21 | } 22 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/chatNotFound.ts: -------------------------------------------------------------------------------- 1 | import { ToastSelectors } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { Page } from '@playwright/test'; 4 | 5 | export class ChatNotFound extends BaseElement { 6 | constructor(page: Page) { 7 | super(page, ToastSelectors.conversationNotFound); 8 | } 9 | 10 | public async getChatNotFoundContent() { 11 | const allContent = await this.getElementsInnerContent(); 12 | return allContent 13 | .join() 14 | .replaceAll(/\u00a0/g, '') 15 | .replaceAll('\n', ''); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/publication/publishConversationsTree.ts: -------------------------------------------------------------------------------- 1 | import { EntitySelectors, PublishingTreeSelectors } from '@/src/ui/selectors'; 2 | import { PublishEntitiesTree } from '@/src/ui/webElements/entityTree/publishEntitiesTree'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class PublishConversationsTree extends PublishEntitiesTree { 6 | constructor(page: Page, parentLocator: Locator) { 7 | super( 8 | page, 9 | parentLocator, 10 | PublishingTreeSelectors.conversationsTree, 11 | EntitySelectors.conversation, 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/disabled-marketplace-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.ConversationsSection, 14 | Feature.Header, 15 | Feature.TopSettings, 16 | Feature.TopChatInfo, 17 | ], 18 | }; 19 | 20 | export default function Index() { 21 | return ; 22 | } 23 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-input-files-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.EmptyChatSettings, 14 | Feature.Header, 15 | Feature.ConversationsSection, 16 | Feature.InputFiles, 17 | ], 18 | }; 19 | 20 | export default function Index() { 21 | return ; 22 | } 23 | -------------------------------------------------------------------------------- /libs/visualizer-connector/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epam/ai-dial-visualizer-connector", 3 | "description": "Package for connecting custom visualizer into DIAL Chat", 4 | "homepage": "https://dialx.ai", 5 | "version": "0.0.1", 6 | "dependencies": { 7 | "@epam/ai-dial-shared": "*" 8 | }, 9 | "type": "module", 10 | "bugs": { 11 | "url": "https://github.com/epam/ai-dial-chat/issues" 12 | }, 13 | "license": "Apache-2.0", 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/epam/ai-dial-chat.git", 17 | "directory": "libs/visualizer-connector" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/sidebar/approveRequiredConversationsTree.ts: -------------------------------------------------------------------------------- 1 | import { ApproveRequiredEntitiesTree } from './approveRequiredEntitiesTree'; 2 | 3 | import { ChatBarSelectors, EntitySelectors } from '@/src/ui/selectors'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class ApproveRequiredConversationsTree extends ApproveRequiredEntitiesTree { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super( 9 | page, 10 | parentLocator, 11 | ChatBarSelectors.approveRequiredConversations(), 12 | EntitySelectors.conversation, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/footer/reportAnIssueModal.ts: -------------------------------------------------------------------------------- 1 | import { IconSelectors, ReportAnIssueModalSelectors } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class ReportAnIssueModal extends BaseElement { 6 | constructor(page: Page, parentLocator?: Locator) { 7 | super( 8 | page, 9 | ReportAnIssueModalSelectors.reportAnIssueContainer, 10 | parentLocator, 11 | ); 12 | } 13 | 14 | public cancelButton = this.getChildElementBySelector( 15 | IconSelectors.cancelIcon, 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/footer/requestApiKeyModal.ts: -------------------------------------------------------------------------------- 1 | import { IconSelectors, RequestApiKeyModalSelectors } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class RequestApiKeyModal extends BaseElement { 6 | constructor(page: Page, parentLocator?: Locator) { 7 | super( 8 | page, 9 | RequestApiKeyModalSelectors.requestApiKeyContainer, 10 | parentLocator, 11 | ); 12 | } 13 | 14 | public cancelButton = this.getChildElementBySelector( 15 | IconSelectors.cancelIcon, 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/IconNonModelWithTooltip.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | 3 | import { Tooltip } from '@/src/components/Common/Tooltip'; 4 | 5 | interface Props { 6 | icon: ReactNode; 7 | isCustomTooltip?: boolean; 8 | tooltipContent: ReactNode; 9 | } 10 | 11 | export const IconNonModelWithTooltip = ({ 12 | icon, 13 | isCustomTooltip, 14 | tooltipContent, 15 | }: Props) => { 16 | if (isCustomTooltip) { 17 | return icon; 18 | } 19 | 20 | return ( 21 | 22 | {icon} 23 | 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /apps/chat/src/store/chat/chat.types.ts: -------------------------------------------------------------------------------- 1 | import { EntityInfo, EntityType } from '@/src/types/common'; 2 | import { ModalState } from '@/src/types/modal'; 3 | 4 | import { MessageFormSchema, MessageFormValue } from '@epam/ai-dial-shared'; 5 | 6 | export interface ChatState { 7 | inputContent: string; 8 | formValue?: MessageFormValue; 9 | configurationSchemas: { modelId: string; schema: MessageFormSchema }[]; 10 | configurationSchemasLoadingIds: string[]; 11 | shouldFocusAndScroll?: boolean; 12 | notAvailableEntityType?: EntityType; 13 | infoModalState: ModalState; 14 | selectedEntityInfo?: EntityInfo; 15 | } 16 | -------------------------------------------------------------------------------- /apps/chat/src/store/overlay/overlay.types.ts: -------------------------------------------------------------------------------- 1 | import { ChatOverlayOptions, MessageButtons } from '@epam/ai-dial-shared'; 2 | 3 | export interface OverlayState { 4 | // Special property to check against when comparing new overlay options 5 | // Do not use for regular usage 6 | _savedOverlayOptions: ChatOverlayOptions | undefined; 7 | 8 | hostDomain: string; 9 | 10 | systemPrompt: string | null; 11 | newConversationsFolder: string | null; 12 | 13 | readyToInteractSent: boolean; 14 | optionsReceived?: boolean; 15 | validationUserEmail: string | null; 16 | 17 | customMessageButtons: MessageButtons[]; 18 | } 19 | -------------------------------------------------------------------------------- /apps/chat/src/hooks/useTranslation.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react'; 2 | 3 | import { useTranslation as useNextTranslation } from 'next-i18next'; 4 | 5 | import { Translation, TranslationOptions } from '@/src/types/translation'; 6 | 7 | export const useTranslation = (translationNamespace: Translation) => { 8 | const { t } = useNextTranslation(translationNamespace); 9 | 10 | const translate = useCallback( 11 | (key: string, options?: TranslationOptions) => 12 | ((options ? t(key, options) : t(key)) as unknown as string) ?? key ?? '', 13 | [t], 14 | ); 15 | return { 16 | t: translate, 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /libs/chat-visualizer-connector/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@epam/ai-dial-chat-visualizer-connector", 3 | "description": "Package for custom visualizer to connect with DIAL Chat", 4 | "homepage": "https://dialx.ai", 5 | "version": "0.0.1", 6 | "dependencies": { 7 | "@epam/ai-dial-shared": "*" 8 | }, 9 | "type": "module", 10 | "bugs": { 11 | "url": "https://github.com/epam/ai-dial-chat/issues" 12 | }, 13 | "license": "Apache-2.0", 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/epam/ai-dial-chat.git", 17 | "directory": "libs/chat-visualizer-connector" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/modulify-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "jsx": "react-jsx", 12 | "composite": true 13 | }, 14 | "files": [], 15 | "include": [], 16 | "references": [ 17 | { 18 | "path": "./tsconfig.lib.json" 19 | }, 20 | { 21 | "path": "./tsconfig.spec.json" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /apps/chat/src/hooks/useUrlHash.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | export const useUrlHash = () => { 4 | const [hash, setHash] = useState(''); 5 | useEffect(() => { 6 | const handleHash = () => { 7 | const newHash = window.location.hash; 8 | 9 | setHash(newHash); 10 | }; 11 | handleHash(); 12 | 13 | window.addEventListener('hashchange', handleHash); 14 | 15 | return () => { 16 | window.removeEventListener('hashchange', handleHash); 17 | }; 18 | }, []); 19 | 20 | const resetHash = () => setHash(''); 21 | 22 | return { 23 | hash, 24 | resetHash, 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /libs/overlay/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": [ 6 | "vitest/globals", 7 | "vitest/importMeta", 8 | "vite/client", 9 | "node", 10 | "vitest" 11 | ] 12 | }, 13 | "include": [ 14 | "vite.config.ts", 15 | "vitest.config.ts", 16 | "src/**/*.test.ts", 17 | "src/**/*.spec.ts", 18 | "src/**/*.test.tsx", 19 | "src/**/*.spec.tsx", 20 | "src/**/*.test.js", 21 | "src/**/*.spec.js", 22 | "src/**/*.test.jsx", 23 | "src/**/*.spec.jsx", 24 | "src/**/*.d.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /libs/shared/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": [ 6 | "vitest/globals", 7 | "vitest/importMeta", 8 | "vite/client", 9 | "node", 10 | "vitest" 11 | ] 12 | }, 13 | "include": [ 14 | "vite.config.ts", 15 | "vitest.config.ts", 16 | "src/**/*.test.ts", 17 | "src/**/*.spec.ts", 18 | "src/**/*.test.tsx", 19 | "src/**/*.spec.tsx", 20 | "src/**/*.test.js", 21 | "src/**/*.spec.js", 22 | "src/**/*.test.jsx", 23 | "src/**/*.spec.jsx", 24 | "src/**/*.d.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /apps/chat-e2e/config/monitoring.playwright.config.ts: -------------------------------------------------------------------------------- 1 | import config from './chat.playwright.config'; 2 | 3 | import { devices } from '@playwright/test'; 4 | 5 | /** 6 | * See https://playwright.dev/docs/test-configuration. 7 | */ 8 | config.projects = [ 9 | { 10 | name: 'auth', 11 | fullyParallel: true, 12 | testMatch: /desktopAuth\.ts/, 13 | }, 14 | { 15 | name: 'monitoring', 16 | testMatch: /\/monitoring\/.*\.test\.ts/, 17 | use: { 18 | ...devices['Desktop Chrome'], 19 | viewport: { width: 1536, height: 864 }, 20 | }, 21 | dependencies: ['auth'], 22 | }, 23 | ]; 24 | 25 | export default config; 26 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/publishing/publishedPromptPreviewModalAssertion.ts: -------------------------------------------------------------------------------- 1 | import { PromptPreviewModalAssertion } from '@/src/assertions/promptPreviewModalAssertion'; 2 | import { PublishedPromptPreviewModal } from '@/src/ui/webElements/publishedPromptPreviewModal'; 3 | 4 | export class PublishedPromptPreviewModalAssertion extends PromptPreviewModalAssertion { 5 | readonly publishedPromptPreviewModal: PublishedPromptPreviewModal; 6 | 7 | constructor(publishedPromptPreviewModal: PublishedPromptPreviewModal) { 8 | super(publishedPromptPreviewModal); 9 | this.publishedPromptPreviewModal = publishedPromptPreviewModal; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/chat/src/store/auth/auth.reducers.ts: -------------------------------------------------------------------------------- 1 | import { SessionContextValue } from 'next-auth/react'; 2 | 3 | import { PayloadAction, createSlice } from '@reduxjs/toolkit'; 4 | 5 | import { AuthState } from './auth.types'; 6 | 7 | const initialState: AuthState = { 8 | session: undefined, 9 | }; 10 | 11 | export const authSlice = createSlice({ 12 | name: 'auth', 13 | initialState, 14 | reducers: { 15 | setSession: ( 16 | state, 17 | { payload }: PayloadAction>, 18 | ) => { 19 | state.session = payload; 20 | }, 21 | }, 22 | }); 23 | 24 | export const AuthActions = authSlice.actions; 25 | -------------------------------------------------------------------------------- /libs/modulify-ui/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": [ 6 | "vitest/globals", 7 | "vitest/importMeta", 8 | "vite/client", 9 | "node", 10 | "vitest" 11 | ] 12 | }, 13 | "include": [ 14 | "vite.config.ts", 15 | "vitest.config.ts", 16 | "src/**/*.test.ts", 17 | "src/**/*.spec.ts", 18 | "src/**/*.test.tsx", 19 | "src/**/*.spec.tsx", 20 | "src/**/*.test.js", 21 | "src/**/*.spec.js", 22 | "src/**/*.test.jsx", 23 | "src/**/*.spec.jsx", 24 | "src/**/*.d.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/headerSelectors.ts: -------------------------------------------------------------------------------- 1 | export const HeaderSelectors = { 2 | headerContainer: '[data-qa="header"]', 3 | leftPanelToggle: '[data-qa="left-panel-toggle"]:visible', 4 | rightPanelToggle: '[data-qa="right-panel-toggle"]:visible', 5 | banner: '[data-qa="banner"]', 6 | accountSettings: '[data-qa="account-settings"]:visible', 7 | newEntity: '[data-qa="new-entity"]', 8 | profilePanel: '[data-qa="profile-panel"]', 9 | settings: '#user-settings-menu-item', 10 | overlayLogout: '#logout-menu-item', 11 | logo: '[data-qa="logo"]', 12 | username: '[data-qa="username"]:visible', 13 | avatar: '[alt="User avatar"]', 14 | }; 15 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityEditor/base/entitySettings/entityEditorEntitySettingsPreviewBody.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChatSelectors, 3 | EntityEditorEntitySettingsPreviewSelectors, 4 | } from '@/src/ui/selectors'; 5 | import { BaseElement } from '@/src/ui/webElements'; 6 | import { Locator, Page } from '@playwright/test'; 7 | 8 | export class EntityEditorEntitySettingsPreviewBody extends BaseElement { 9 | constructor(page: Page, parentLocator: Locator) { 10 | super(page, EntityEditorEntitySettingsPreviewSelectors.body, parentLocator); 11 | } 12 | 13 | public previewSpinner = this.getChildElementBySelector(ChatSelectors.spinner); 14 | } 15 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/unshare-user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/ChatInput/ChatInputFooter.tsx: -------------------------------------------------------------------------------- 1 | import { ScreenState } from '@/src/types/common'; 2 | 3 | import { FooterMessage } from '@/src/components/Common/FooterMessage'; 4 | import { withRenderForScreen } from '@/src/components/Common/ScreenRender'; 5 | 6 | function ChatInputFooterView() { 7 | return ( 8 |
9 | 10 |
11 | ); 12 | } 13 | 14 | export const ChatInputFooter = withRenderForScreen([ 15 | ScreenState.MD, 16 | ScreenState.XL, 17 | ScreenState.XL3, 18 | ScreenState.XL4, 19 | ScreenState.XL5, 20 | ])(ChatInputFooterView); 21 | -------------------------------------------------------------------------------- /apps/chat/src/store/files/files.types.ts: -------------------------------------------------------------------------------- 1 | import { DialFile, FileFolderInterface } from '@/src/types/files'; 2 | 3 | import { UploadStatus } from '@epam/ai-dial-shared'; 4 | 5 | export interface FilesState { 6 | initialized: boolean; 7 | files: DialFile[]; 8 | selectedFilesIds: string[]; 9 | filesStatus: UploadStatus; 10 | 11 | chosenFileIds: string[]; 12 | chosenEmptyFoldersIds: string[]; 13 | 14 | folders: FileFolderInterface[]; 15 | foldersStatus: UploadStatus; 16 | loadingFolderId?: string; 17 | newAddedFolderId?: string; 18 | lastRenamedParentFolder?: { oldId: string; newId: string }; 19 | sharedFileIds: string[]; 20 | } 21 | -------------------------------------------------------------------------------- /libs/visualizer-connector/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": [ 6 | "vitest/globals", 7 | "vitest/importMeta", 8 | "vite/client", 9 | "node", 10 | "vitest" 11 | ] 12 | }, 13 | "include": [ 14 | "vite.config.ts", 15 | "vitest.config.ts", 16 | "src/**/*.test.ts", 17 | "src/**/*.spec.ts", 18 | "src/**/*.test.tsx", 19 | "src/**/*.spec.tsx", 20 | "src/**/*.test.js", 21 | "src/**/*.spec.js", 22 | "src/**/*.test.jsx", 23 | "src/**/*.spec.jsx", 24 | "src/**/*.d.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /libs/chat-visualizer-connector/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": [ 6 | "vitest/globals", 7 | "vitest/importMeta", 8 | "vite/client", 9 | "node", 10 | "vitest" 11 | ] 12 | }, 13 | "include": [ 14 | "vite.config.ts", 15 | "vitest.config.ts", 16 | "src/**/*.test.ts", 17 | "src/**/*.spec.ts", 18 | "src/**/*.test.tsx", 19 | "src/**/*.spec.tsx", 20 | "src/**/*.test.js", 21 | "src/**/*.spec.js", 22 | "src/**/*.test.jsx", 23 | "src/**/*.spec.jsx", 24 | "src/**/*.d.ts" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/Publish/PublicationHandler/ReviewRowItems/PublicationFileRow.tsx: -------------------------------------------------------------------------------- 1 | import { IconFile } from '@tabler/icons-react'; 2 | 3 | import { BackendResourceTypeName } from '@/src/types/common'; 4 | 5 | import { PublicationItemRow } from './PublicationItemRow'; 6 | import { PublicationItemProps } from './view-props'; 7 | 8 | export const PublicationFileRow: React.FC = (props) => { 9 | return ( 10 | } 13 | itemTypeName={BackendResourceTypeName.FILE} 14 | dataQa="file" 15 | /> 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-empty-chat-settings-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.EmptyChatSettings, 14 | Feature.Header, 15 | Feature.ConversationsSection, 16 | Feature.TopSettings, 17 | Feature.TopClearConversation, 18 | ], 19 | }; 20 | 21 | export default function Index() { 22 | return ; 23 | } 24 | -------------------------------------------------------------------------------- /libs/shared/src/constants/visualizer-connector.ts: -------------------------------------------------------------------------------- 1 | export const visualizerConnectorLibName = 'VisualizerConnector'; 2 | 3 | export enum VisualizerConnectorEvents { 4 | initReady = 'INIT_READY', 5 | ready = 'READY', 6 | readyToInteract = 'READY_TO_INTERACT', 7 | sendMessage = 'SEND_MESSAGE', 8 | createdConversationSuccess = 'CREATED_CONVERSATION_SUCCESS', 9 | updatedConversationSuccess = 'UPDATED_CONVERSATION_SUCCESS', 10 | updatedApplicationSuccess = 'UPDATED_APPLICATION_SUCCESS', 11 | } 12 | 13 | export enum VisualizerConnectorRequests { 14 | sendVisualizeData = 'SEND_VISUALIZE_DATA', 15 | setVisualizerOptions = 'SET_VISUALIZER_OPTIONS', 16 | } 17 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/conversationInfoTooltipAssertion.ts: -------------------------------------------------------------------------------- 1 | import { BaseAssertion } from '@/src/assertions/base/baseAssertion'; 2 | import { ModelInfoTooltip } from '@/src/ui/webElements'; 3 | 4 | export class ConversationInfoTooltipAssertion extends BaseAssertion { 5 | readonly modelInfoTooltip: ModelInfoTooltip; 6 | 7 | constructor(modelInfoTooltip: ModelInfoTooltip) { 8 | super(); 9 | this.modelInfoTooltip = modelInfoTooltip; 10 | } 11 | 12 | public async assertTooltipModelIcon(expectedIcon: string) { 13 | await super.assertEntityIcon( 14 | this.modelInfoTooltip.getModelIcon(), 15 | expectedIcon, 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/arrow-up-right-from-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/Publish/PublicationHandler/ReviewRowItems/PublicationPromptRow.tsx: -------------------------------------------------------------------------------- 1 | import { IconBulb } from '@tabler/icons-react'; 2 | 3 | import { BackendResourceTypeName } from '@/src/types/common'; 4 | 5 | import { PublicationItemRow } from './PublicationItemRow'; 6 | import { PublicationItemProps } from './view-props'; 7 | 8 | export const PublicationPromptRow: React.FC = (props) => { 9 | return ( 10 | } 13 | itemTypeName={BackendResourceTypeName.PROMPT} 14 | dataQa="prompt" 15 | /> 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /apps/chat/src/components/Sidebar/ResizeIcons.tsx: -------------------------------------------------------------------------------- 1 | import { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'; 2 | 3 | interface ResizeIconProps { 4 | className: string; 5 | } 6 | 7 | export const LeftSideResizeIcon = ({ className }: ResizeIconProps) => { 8 | return ( 9 |
10 | 11 |
12 | ); 13 | }; 14 | 15 | export const RightSideResizeIcon = ({ className }: ResizeIconProps) => { 16 | return ( 17 |
18 | 19 |
20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | day: "wednesday" 8 | time: "09:00" 9 | # Disable version updates, keep security updates only 10 | open-pull-requests-limit: 0 11 | commit-message: 12 | # Prefix all commit messages with "chore: " 13 | prefix: "chore" 14 | - package-ecosystem: "github-actions" 15 | directory: "/" 16 | schedule: 17 | interval: "weekly" 18 | day: "wednesday" 19 | time: "09:00" 20 | commit-message: 21 | # Prefix all commit messages with "chore: " 22 | prefix: "chore" 23 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/__tests__/file.test.ts: -------------------------------------------------------------------------------- 1 | import { isAbsoluteUrl } from '../file'; 2 | 3 | describe('File utility methods', () => { 4 | it.each([ 5 | ['http://test.com'], 6 | ['https://test.com'], 7 | ['ftp://test.com'], 8 | ['file://test.com'], 9 | ['data:some_data'], 10 | ['//abc/cde'], 11 | ])('isAbsoluteUrl (%s, %s, %s, %s) returns true', (url) => { 12 | expect(isAbsoluteUrl(url)).toBe(true); 13 | }); 14 | 15 | it.each([['/test/test1'], ['abc'], ['abc/cde'], ['1/2/3']])( 16 | 'isAbsoluteUrl (%s, %s, %s, %s) returns false', 17 | (url) => { 18 | expect(isAbsoluteUrl(url)).toBe(false); 19 | }, 20 | ); 21 | }); 22 | -------------------------------------------------------------------------------- /libs/shared/src/utils/__tests__/features.test.ts: -------------------------------------------------------------------------------- 1 | import { Feature } from '../../types/features'; 2 | import { validateFeature } from '../features'; 3 | 4 | import { test } from 'vitest'; 5 | 6 | describe('validateFeature', () => { 7 | test('should return true when feature is available', () => { 8 | const feature = Feature.AttachmentsManager; 9 | const result = validateFeature(feature); 10 | expect(result).toBe(true); 11 | }); 12 | 13 | test('should return false when feature is not available', () => { 14 | const feature = 'nonExistentFeature'; 15 | const result = validateFeature(feature); 16 | expect(result).toBe(false); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/ErrorTooltip.tsx: -------------------------------------------------------------------------------- 1 | import { IconExclamationCircle } from '@tabler/icons-react'; 2 | 3 | import classNames from 'classnames'; 4 | 5 | import { Tooltip, TooltipOptions } from './Tooltip'; 6 | 7 | export function ErrorTooltip(props: Omit) { 8 | return ( 9 | 13 | 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /apps/chat/src/constants/toolsets.ts: -------------------------------------------------------------------------------- 1 | import { translate } from '@/src/utils/app/translation'; 2 | 3 | import { ApiKeys } from '@/src/types/common'; 4 | 5 | export enum ToolsetEditorQuery { 6 | Id = 'id', 7 | PublicationUrl = 'publicationUrl', 8 | Step = 'step', 9 | ReturnUrl = 'returnUrl', 10 | IsCreating = 'isCreating', 11 | } 12 | 13 | export const DRAFT_TOOLSET_ID = `${ApiKeys.Toolsets}/draft`; 14 | 15 | export enum ToolsetAuthAction { 16 | LoginWithMyCreds = 'Login with my creds', 17 | LogIn = 'Log in', 18 | LogOut = 'Log out', 19 | } 20 | 21 | export const PUBLIC_TOOLSET_TOOLTIP = translate( 22 | 'This toolset is public and cannot be edited', 23 | ); 24 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/disabled-default-buttons/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.Header, 14 | Feature.ConversationsSection, 15 | Feature.HideEditUserMessage, 16 | Feature.HideRegenerateAssistantMessage, 17 | Feature.HideDeleteUserMessage, 18 | ], 19 | }; 20 | 21 | export default function Index() { 22 | return ; 23 | } 24 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/key.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/Spinner.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | 3 | import LoaderIcon from '@/public/images/icons/loader.svg'; 4 | 5 | interface Props { 6 | size?: number; 7 | className?: string; 8 | dataQa?: string; 9 | } 10 | 11 | export const Spinner = ({ 12 | size = 16, 13 | className = '', 14 | dataQa = 'entity-spinner', 15 | }: Props) => { 16 | return ( 17 | 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/pages/overlay/overlayMarketplacePage.ts: -------------------------------------------------------------------------------- 1 | import { OverlayBasePage } from '@/src/ui/pages/overlay/overlayBasePage'; 2 | import { MarketplaceContainer } from '@/src/ui/webElements'; 3 | import { Page } from '@playwright/test'; 4 | 5 | export class OverlayMarketplacePage extends OverlayBasePage { 6 | constructor(page: Page) { 7 | super(page, new MarketplaceContainer(page)); 8 | } 9 | 10 | getMarketplaceContainer() { 11 | return this.getOverlayContainer(); 12 | } 13 | 14 | async waitForPageLoaded() { 15 | await this.getMarketplaceContainer() 16 | .getChatLoader() 17 | .waitForState({ state: 'hidden' }); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/file-arrow-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/folderSelectors.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | 3 | export const FolderSelectors = { 4 | folder: '[data-qa="folder"]', 5 | rootFolder: () => `${FolderSelectors.folder}[property="root"]`, 6 | childFolder: () => `${FolderSelectors.folder}[property="child"]`, 7 | folderGroup: '#folder', 8 | folderName: '[data-qa="folder-name"]', 9 | emptyFolderName: () => `${FolderSelectors.folderName}:not(:has(*))`, 10 | folderNameWithContent: () => `${FolderSelectors.folderName} > ${Tags.span}`, 11 | folderCheckbox: '[data-item-checkbox="true"]', 12 | folderInput: '[data-qa="folder-input"]', 13 | iconContainer: '[data-qa="icon-container"]', 14 | }; 15 | -------------------------------------------------------------------------------- /apps/chat/src/types/store.ts: -------------------------------------------------------------------------------- 1 | import { NextRouter } from 'next/router'; 2 | 3 | import { Epic } from 'redux-observable'; 4 | 5 | import * as allActions from '@/src/store/actions'; 6 | 7 | import { rootReducer } from '@/src/store'; 8 | 9 | type ExtractAction = 10 | T extends Record infer R> ? R : never; 11 | 12 | export type AppAction = ExtractAction< 13 | { 14 | [K in keyof typeof allActions]: (typeof allActions)[K]; 15 | }[keyof typeof allActions] 16 | >; 17 | 18 | export type RootState = ReturnType; 19 | 20 | export type AppEpic = Epic< 21 | AppAction, 22 | AppAction, 23 | RootState, 24 | { router: NextRouter } 25 | >; 26 | -------------------------------------------------------------------------------- /apps/chat/src/types/search.ts: -------------------------------------------------------------------------------- 1 | import { ShareEntity } from '@epam/ai-dial-shared'; 2 | 3 | export enum SearchFilters { 4 | None = 0, 5 | SharedByMe = 1 << 0, 6 | PublishedByMe = 1 << 1, 7 | } 8 | 9 | export type EntityFilter = (item: T) => boolean; 10 | export type EntityVersionFilter = (item: T, version: string) => boolean; 11 | 12 | export interface EntityFilters { 13 | sectionFilter?: EntityFilter; // filter root level folders and items e.g. "Shared with me" 14 | searchFilter?: EntityFilter; // filter specific level folders and items e.g. "Shared by me" 15 | versionFilter?: EntityVersionFilter; // filter items whose versions are selected 16 | } 17 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/ChatCompareRotate.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from '@/src/hooks/useTranslation'; 2 | 3 | import { Translation } from '@/src/types/translation'; 4 | 5 | import Rotate from '@/public/images/icons/rotate.svg'; 6 | 7 | export const ChatCompareRotate = () => { 8 | const { t } = useTranslation(Translation.Chat); 9 | 10 | return ( 11 |
12 |
13 | 14 |
15 |
16 | {t('Please rotate the screen to use compare mode')} 17 |
18 |
19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/enabled-marketplace-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | enabledFeatures: [ 13 | Feature.ConversationsSection, 14 | Feature.Header, 15 | Feature.TopSettings, 16 | Feature.TopChatInfo, 17 | Feature.Marketplace, 18 | Feature.CodeApps, 19 | Feature.CustomApplications, 20 | ], 21 | }; 22 | 23 | export default function Index() { 24 | return ; 25 | } 26 | -------------------------------------------------------------------------------- /libs/shared/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; 2 | import { defineConfig } from 'vite'; 3 | 4 | export default defineConfig({ 5 | root: __dirname, 6 | 7 | plugins: [nxViteTsPaths()], 8 | 9 | // Uncomment this if you are using workers. 10 | // worker: { 11 | // plugins: [ nxViteTsPaths() ], 12 | // }, 13 | 14 | test: { 15 | globals: true, 16 | cache: false, 17 | environment: 'node', 18 | include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], 19 | reporters: ['default'], 20 | coverage: { 21 | reportsDirectory: '../../coverage/libs/shared', 22 | provider: 'v8', 23 | }, 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/toast.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | import { ToastSelectors } from '@/src/ui/selectors'; 3 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class Toast extends BaseElement { 7 | constructor(page: Page, parentLocator?: Locator) { 8 | super(page, ToastSelectors.toast, parentLocator); 9 | } 10 | 11 | public closeButton = this.getChildElementBySelector(Tags.button); 12 | 13 | public async closeToast() { 14 | if (await this.isVisible()) { 15 | await this.closeButton.click(); 16 | await this.waitForState({ state: 'hidden' }); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/chat/index.d.ts: -------------------------------------------------------------------------------- 1 | import { DefaultSession } from 'next-auth'; 2 | import { DefaultJWT } from 'next-auth/jwt'; 3 | 4 | /* eslint-disable @typescript-eslint/no-explicit-any */ 5 | declare module '*.svg' { 6 | const content: any; 7 | export const ReactComponent: any; 8 | export default content; 9 | } 10 | 11 | type UserData = { 12 | isAdmin: boolean; 13 | } & Record; 14 | 15 | declare module 'next-auth' { 16 | interface Session { 17 | user: UserData & DefaultSession['user']; 18 | providerId: string; 19 | } 20 | } 21 | 22 | declare module 'next-auth/jwt' { 23 | interface JWT extends DefaultJWT { 24 | user?: Partial; 25 | access_token?: string; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/Loader.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | 3 | import { Spinner } from './Spinner'; 4 | 5 | interface Props { 6 | size?: number; 7 | containerClassName?: string; 8 | loaderClassName?: string; 9 | dataQa?: string; 10 | } 11 | 12 | export function Loader({ 13 | size = 45, 14 | containerClassName, 15 | loaderClassName, 16 | dataQa = 'chat-loader', 17 | }: Props) { 18 | return ( 19 |
25 | 26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/data/bucket-service.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | import { ApiUtils } from '@/src/utils/server/api'; 4 | 5 | import { HTTPMethod } from '@/src/types/http'; 6 | 7 | export class BucketService { 8 | private static bucket: string; 9 | public static requestBucket(): Observable<{ bucket: string }> { 10 | return ApiUtils.request('/api/bucket', { 11 | method: HTTPMethod.GET, 12 | headers: { 13 | 'Content-Type': 'application/json', 14 | }, 15 | }); 16 | } 17 | 18 | public static getBucket(): string { 19 | return this.bucket; 20 | } 21 | 22 | public static setBucket(bucket: string): void { 23 | this.bucket = bucket; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/app/cases/overlay/overlay-conversation-id-set-sandbox/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { 4 | ChatOverlayWrapper, 5 | commonOverlayProps, 6 | } from '../../components/chatOverlayWrapper'; 7 | 8 | import { Feature } from '@epam/ai-dial-shared'; 9 | 10 | const overlayOptions = { 11 | ...commonOverlayProps, 12 | overlayConversationId: 13 | 'conversations/public/playback__[Playback] overlayConversationName__0.0.1', 14 | enabledFeatures: [ 15 | Feature.ConversationsSection, 16 | Feature.ConversationsPublishing, 17 | Feature.Header, 18 | ], 19 | }; 20 | 21 | export default function Index() { 22 | return ; 23 | } 24 | -------------------------------------------------------------------------------- /libs/modulify-ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; 2 | import { defineConfig } from 'vite'; 3 | 4 | export default defineConfig({ 5 | root: __dirname, 6 | 7 | plugins: [nxViteTsPaths()], 8 | 9 | // Uncomment this if you are using workers. 10 | // worker: { 11 | // plugins: [ nxViteTsPaths() ], 12 | // }, 13 | 14 | test: { 15 | globals: true, 16 | cache: false, 17 | environment: 'jsdom', 18 | include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], 19 | reporters: ['default'], 20 | coverage: { 21 | reportsDirectory: '../../coverage/libs/modulify-ui', 22 | provider: 'v8', 23 | }, 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/pages/overlay/overlayLoginPage.ts: -------------------------------------------------------------------------------- 1 | import { BasePage } from '@/src/ui/pages/basePage'; 2 | import { OverlaySelectors } from '@/src/ui/selectors'; 3 | import { BaseElement } from '@/src/ui/webElements'; 4 | 5 | export class OverlayLoginPage extends BasePage { 6 | public loginButton = new BaseElement( 7 | this.page, 8 | '', 9 | this.page.frameLocator(OverlaySelectors.overlayFrame).getByText('Login'), 10 | ); 11 | 12 | public async clickLoginButton() { 13 | const [newPage] = await Promise.all([ 14 | this.page.context().waitForEvent('page'), 15 | await this.loginButton.click(), 16 | ]); 17 | await newPage.waitForLoadState(); 18 | return newPage; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityEditor/base/entityEditorForm.ts: -------------------------------------------------------------------------------- 1 | import { BaseElement } from '@/src/ui/webElements'; 2 | import { FieldLabel } from '@/src/ui/webElements/fieldLabel'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export abstract class EntityEditorForm extends BaseElement { 6 | protected fieldLabelHelper: FieldLabel; 7 | 8 | public getRequiredIndicator(fieldName: string) { 9 | return this.fieldLabelHelper.getFieldRequiredIndicator(fieldName); 10 | } 11 | 12 | protected constructor(page: Page, selector: string, parentLocator?: Locator) { 13 | super(page, selector, parentLocator); 14 | this.fieldLabelHelper = new FieldLabel(page, this.rootLocator); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/chat/src/store/toolset/toolset.types.ts: -------------------------------------------------------------------------------- 1 | import { PublishRequestDialAIEntityModel } from '@/src/types/models'; 2 | import { 3 | ToolsetEditorSteps, 4 | ToolsetModel, 5 | ToolsetsMap, 6 | } from '@/src/types/toolsets'; 7 | 8 | import { UploadStatus } from '@epam/ai-dial-shared'; 9 | 10 | export interface ToolsetState { 11 | initialized: boolean; 12 | toolsetsMap: ToolsetsMap; 13 | toolsetsStatus: UploadStatus; 14 | 15 | toolsetDetails?: ToolsetModel; 16 | toolsetDetailsStatus: UploadStatus; 17 | 18 | installedToolsets: string[]; 19 | isInstalledToolsetsInitialized: boolean; 20 | 21 | editorStep: ToolsetEditorSteps; 22 | 23 | publishRequestToolsets: PublishRequestDialAIEntityModel[]; 24 | } 25 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/errorPopup.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | import { Popup } from '@/src/ui/selectors/dialogSelectors'; 3 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 4 | import { Page } from '@playwright/test'; 5 | 6 | export class ErrorPopup extends BaseElement { 7 | constructor(page: Page) { 8 | super(page, Popup.errorPopup); 9 | } 10 | 11 | public cancelButton = this.getChildElementBySelector(Tags.button); 12 | 13 | public async cancelPopup() { 14 | const isPopupVisible = await this.isVisible(); 15 | if (isPopupVisible) { 16 | await this.cancelButton.click(); 17 | await this.waitForState({ state: 'hidden' }); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/caret-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/caret-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/FilesSelector/NoFiles.tsx: -------------------------------------------------------------------------------- 1 | import { IconFile } from '@tabler/icons-react'; 2 | 3 | import { useTranslation } from 'next-i18next'; 4 | 5 | import { Translation } from '@/src/types/translation'; 6 | 7 | interface Props { 8 | caption?: string; 9 | } 10 | 11 | export const NoFiles: React.FC = ({ 12 | caption = 'No documents added', 13 | }) => { 14 | const { t } = useTranslation(Translation.Files); 15 | 16 | return ( 17 |
18 | 19 | {t(caption)} 20 |
21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/applications/customApplicationBuilder.ts: -------------------------------------------------------------------------------- 1 | import { ApiApplicationModelRegular } from '@/chat/types/applications'; 2 | import { ExpectedConstants } from '@/src/testData'; 3 | import { ApplicationBuilderBase } from '@/src/testData/applications/applicationBuilderBase'; 4 | 5 | export class CustomApplicationBuilder extends ApplicationBuilderBase { 6 | withEndpoint(endpoint: string): this { 7 | this.application.endpoint = endpoint; 8 | return this; 9 | } 10 | 11 | protected reset(): ApiApplicationModelRegular { 12 | this.application = super.reset(); 13 | this.application.endpoint = ExpectedConstants.defaultEntityUrl; 14 | return this.application; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/footer.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | import { ChatSelectors } from '@/src/ui/selectors'; 3 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class Footer extends BaseElement { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super(page, ChatSelectors.footer, parentLocator); 9 | } 10 | 11 | public async openFooterLink(linkText?: string) { 12 | linkText 13 | ? await this.getChildElementBySelector(Tags.a) 14 | .getElementLocatorByText(linkText) 15 | .click() 16 | : await this.getChildElementBySelector(Tags.a).getNthElement(1).click(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/NoData.tsx: -------------------------------------------------------------------------------- 1 | import { IconClipboardX } from '@tabler/icons-react'; 2 | 3 | import { useTranslation } from '@/src/hooks/useTranslation'; 4 | 5 | import { Translation } from '@/src/types/translation'; 6 | 7 | export const NoData = () => { 8 | const { t } = useTranslation(Translation.Common); 9 | 10 | return ( 11 |
15 | 22 | {t('No data')} 23 |
24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /apps/chat/src/types/parse-entity.ts: -------------------------------------------------------------------------------- 1 | export interface ParseEntityApiKeyOptions { 2 | parseModel?: boolean; 3 | parseVersion?: boolean; 4 | defaultVersion?: string; 5 | } 6 | 7 | interface ModelInfo { 8 | model: { id: string }; 9 | isPlayback: boolean; 10 | isReplay: boolean; 11 | } 12 | 13 | // version will be string if parseVersion is true, modelInfo will be ModelInfo if parseModel is true 14 | export type ParseEntityApiKeyResult = { 15 | name: string; 16 | } & (T extends { parseModel: true } 17 | ? { 18 | modelInfo: ModelInfo; 19 | } 20 | : { modelInfo?: ModelInfo }) & 21 | (T extends { parseVersion: true } 22 | ? { version: string } 23 | : { version?: string }); 24 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityEditor/customApp/customAppEditorAppSettingsPreviewBody.ts: -------------------------------------------------------------------------------- 1 | import { 2 | EntityEditorEntitySettingsPreviewBody, 3 | EntityEditorEntitySettingsPreviewChat, 4 | } from '@/src/ui/webElements'; 5 | 6 | export class CustomAppEditorAppSettingsPreviewBody extends EntityEditorEntitySettingsPreviewBody { 7 | private appEditorAppSettingsPreviewChat!: EntityEditorEntitySettingsPreviewChat; 8 | 9 | public getAppEditorAppSettingsPreviewChat() { 10 | if (!this.appEditorAppSettingsPreviewChat) { 11 | this.appEditorAppSettingsPreviewChat = 12 | new EntityEditorEntitySettingsPreviewChat(this.page, this.rootLocator); 13 | } 14 | return this.appEditorAppSettingsPreviewChat; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/chat/src/utils/server/logger.ts: -------------------------------------------------------------------------------- 1 | import pino from 'pino'; 2 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 3 | import transport from 'pino-opentelemetry-transport'; 4 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 5 | import pretty from 'pino-pretty'; 6 | 7 | export const logger = pino({ 8 | transport: { 9 | target: 'pino-opentelemetry-transport', 10 | options: { 11 | logRecordProcessorOptions: [ 12 | { recordProcessorType: 'batch', exporterOptions: { protocol: 'http' } }, 13 | { 14 | recordProcessorType: 'simple', 15 | exporterOptions: { 16 | protocol: 'console', 17 | }, 18 | }, 19 | ], 20 | }, 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/actions/auth0Login.ts: -------------------------------------------------------------------------------- 1 | import { LocalStorageManager } from '@/src/core/localStorageManager'; 2 | import { ProviderLogin } from '@/src/ui/actions/providerLogin'; 3 | import { Auth0Page } from '@/src/ui/pages/auth0Page'; 4 | import { LoginPage } from '@/src/ui/pages/loginPage'; 5 | import { BaseElement } from '@/src/ui/webElements'; 6 | 7 | export class Auth0Login extends ProviderLogin { 8 | constructor( 9 | loginPage: LoginPage, 10 | authProviderPage: Auth0Page, 11 | localStorageManager: LocalStorageManager, 12 | ) { 13 | super(loginPage, authProviderPage, localStorageManager); 14 | } 15 | 16 | getSignInButton(): BaseElement { 17 | return this.loginPage.auth0SignInButton; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/actions/keycloakLogin.ts: -------------------------------------------------------------------------------- 1 | import { LocalStorageManager } from '@/src/core/localStorageManager'; 2 | import { ProviderLogin } from '@/src/ui/actions/providerLogin'; 3 | import { KeycloakPage } from '@/src/ui/pages'; 4 | import { LoginPage } from '@/src/ui/pages/loginPage'; 5 | import { BaseElement } from '@/src/ui/webElements'; 6 | 7 | export class KeycloakLogin extends ProviderLogin { 8 | constructor( 9 | loginPage: LoginPage, 10 | authProviderPage: KeycloakPage, 11 | localStorageManager: LocalStorageManager, 12 | ) { 13 | super(loginPage, authProviderPage, localStorageManager); 14 | } 15 | 16 | getSignInButton(): BaseElement { 17 | return this.loginPage.keycloakSignInButton; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/changePath.ts: -------------------------------------------------------------------------------- 1 | import { AttributeValues } from '@/src/ui/domData'; 2 | import { ChangePathElement } from '@/src/ui/selectors'; 3 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 4 | import { Button } from '@/src/ui/webElements/common/button'; 5 | import { Locator, Page } from '@playwright/test'; 6 | 7 | export class ChangePath extends BaseElement { 8 | constructor(page: Page, parentLocator: Locator) { 9 | super(page, ChangePathElement.changePathContainer, parentLocator); 10 | } 11 | 12 | public path = this.getChildElementBySelector(ChangePathElement.path); 13 | 14 | public changeButton = new Button( 15 | this.page, 16 | AttributeValues.change, 17 | this.rootLocator, 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityEditor/base/general/entityEditorPreviewToggle.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | import { EntityEditorPreviewToggleSelectors } from '@/src/ui/selectors'; 3 | import { BaseElement } from '@/src/ui/webElements'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class EntityEditorPreviewToggle extends BaseElement { 7 | constructor(page: Page, parentLocator?: Locator) { 8 | super( 9 | page, 10 | EntityEditorPreviewToggleSelectors.toggleContainer, 11 | parentLocator, 12 | ); 13 | } 14 | 15 | public detailedSwitch = this.getChildElementBySelector( 16 | EntityEditorPreviewToggleSelectors.detailedSwitch, 17 | ).getChildElementBySelector(Tags.label); 18 | } 19 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/ScrollDownButton.tsx: -------------------------------------------------------------------------------- 1 | import { IconArrowDown } from '@tabler/icons-react'; 2 | 3 | import classNames from 'classnames'; 4 | 5 | import { DialButton } from '@epam/ai-dial-ui-kit'; 6 | 7 | interface Props { 8 | onScrollDownClick: () => void; 9 | className?: string; 10 | } 11 | export const ScrollDownButton = ({ onScrollDownClick, className }: Props) => { 12 | return ( 13 |
14 | } 19 | /> 20 |
21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/actions/azureADLogin.ts: -------------------------------------------------------------------------------- 1 | import { LocalStorageManager } from '@/src/core/localStorageManager'; 2 | import { ProviderLogin } from '@/src/ui/actions/providerLogin'; 3 | import { AzureADPage } from '@/src/ui/pages/azureADPage'; 4 | import { LoginPage } from '@/src/ui/pages/loginPage'; 5 | import { BaseElement } from '@/src/ui/webElements'; 6 | 7 | export class AzureADLogin extends ProviderLogin { 8 | constructor( 9 | loginPage: LoginPage, 10 | authProviderPage: AzureADPage, 11 | localStorageManager: LocalStorageManager, 12 | ) { 13 | super(loginPage, authProviderPage, localStorageManager); 14 | } 15 | 16 | getSignInButton(): BaseElement { 17 | return this.loginPage.keycloakSignInButton; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/message-square-lines-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /libs/shared/src/types/visualizer-connector.ts: -------------------------------------------------------------------------------- 1 | import { DialLibRequest, Styles } from './common'; 2 | 3 | export interface VisualizerConnectorOptions { 4 | domain: string; 5 | hostDomain: string; 6 | visualizerName: string; 7 | loaderStyles?: Styles; 8 | loaderClass?: string; 9 | loaderInnerHTML?: string; 10 | 11 | requestTimeout?: number; 12 | } 13 | 14 | export type VisualizerConnectorRequest = DialLibRequest; 15 | 16 | export interface CustomVisualizerDataLayout { 17 | width: number; 18 | height: number; 19 | themeId?: string; 20 | } 21 | export interface CustomVisualizerData { 22 | layout: CustomVisualizerDataLayout; 23 | } 24 | export interface AttachmentData { 25 | mimeType: string; 26 | visualizerData: CustomVisualizerData; 27 | } 28 | -------------------------------------------------------------------------------- /apps/chat/src/components/Badge.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | 3 | interface BadgeProps { 4 | label: string; 5 | type?: 'error' | 'success' | 'warning'; 6 | className?: string; 7 | } 8 | 9 | export const Badge = ({ label, type, className }: BadgeProps) => ( 10 | 23 | {label} 24 | 25 | ); 26 | -------------------------------------------------------------------------------- /apps/chat/src/components/Buttons/CloseSidebarButton.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | 3 | import { DialCloseButton } from '@epam/ai-dial-ui-kit'; 4 | 5 | interface Props { 6 | onClose: () => void; 7 | isLeftSide: boolean; 8 | } 9 | 10 | export const CloseSidebarButton: React.FC = ({ 11 | onClose, 12 | isLeftSide, 13 | }) => { 14 | return ( 15 |
21 | 26 |
27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /apps/chat/src/components/Buttons/SidebarActionButton.tsx: -------------------------------------------------------------------------------- 1 | import { MouseEventHandler, ReactElement } from 'react'; 2 | 3 | import { DialButton } from '@epam/ai-dial-ui-kit'; 4 | 5 | interface Props { 6 | handleClick: MouseEventHandler; 7 | iconBefore?: ReactElement; 8 | iconAfter?: ReactElement; 9 | label?: string; 10 | dataQA?: string; 11 | } 12 | 13 | export const SidebarActionButton = ({ 14 | handleClick, 15 | iconBefore, 16 | iconAfter, 17 | label, 18 | dataQA, 19 | }: Props) => ( 20 | 28 | ); 29 | -------------------------------------------------------------------------------- /apps/chat/src/types/folder.ts: -------------------------------------------------------------------------------- 1 | import { PromptInfo } from './prompt'; 2 | import { EntityFilters } from './search'; 3 | 4 | import { ConversationInfo, FolderInterface } from '@epam/ai-dial-shared'; 5 | 6 | export type { FolderInterface }; 7 | 8 | export interface FoldersAndEntities { 9 | folders: FolderInterface[]; 10 | entities: T[]; 11 | } 12 | 13 | export interface FolderSectionProps { 14 | hidden?: boolean; 15 | name: string; 16 | dataQa: string; 17 | hideIfEmpty?: boolean; 18 | displayRootFiles?: boolean; 19 | filters: EntityFilters; 20 | showEmptyFolders?: boolean; 21 | openByDefault?: boolean; 22 | } 23 | 24 | export interface DraggedInterface { 25 | entity: FolderInterface | ConversationInfo | PromptInfo; 26 | isFolder: boolean; 27 | } 28 | -------------------------------------------------------------------------------- /libs/shared/src/utils/Task.ts: -------------------------------------------------------------------------------- 1 | export class Task { 2 | protected promise: Promise; 3 | protected resolve!: (value: boolean) => void; 4 | protected reject!: (reason: string) => void; 5 | 6 | protected isResolved: boolean; 7 | 8 | constructor() { 9 | this.isResolved = false; 10 | this.promise = new Promise((resolve, reject) => { 11 | this.resolve = resolve; 12 | this.reject = reject; 13 | }); 14 | } 15 | 16 | complete() { 17 | if (this.isResolved) return; 18 | 19 | this.isResolved = true; 20 | this.resolve(true); 21 | } 22 | 23 | fail(reason = 'Task failed') { 24 | if (this.isResolved) return; 25 | 26 | this.reject(reason); 27 | } 28 | 29 | ready() { 30 | return this.promise; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/notFound.ts: -------------------------------------------------------------------------------- 1 | import { NotFoundSelectors } from '@/src/ui/selectors/notFoundSelectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { Page } from '@playwright/test'; 4 | 5 | export class NotFound extends BaseElement { 6 | constructor(page: Page) { 7 | super(page, NotFoundSelectors.container); 8 | } 9 | 10 | public header = this.getChildElementBySelector(NotFoundSelectors.header); 11 | public title = this.getChildElementBySelector(NotFoundSelectors.title); 12 | public description = this.getChildElementBySelector( 13 | NotFoundSelectors.description, 14 | ); 15 | public newConversationButton = this.getChildElementBySelector( 16 | NotFoundSelectors.newConversationButton, 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/publishedPromptPreviewModal.ts: -------------------------------------------------------------------------------- 1 | import { PromptPreviewModalWindow } from '@/src/ui/webElements/promptPreviewModalWindow'; 2 | import { PublicationReviewControl } from '@/src/ui/webElements/publicationReviewControl'; 3 | import { Page } from 'playwright-chromium'; 4 | 5 | export class PublishedPromptPreviewModal extends PromptPreviewModalWindow { 6 | constructor(page: Page) { 7 | super(page); 8 | this.publicationReviewControl = new PublicationReviewControl( 9 | this.page, 10 | this.rootLocator, 11 | ); 12 | } 13 | 14 | private readonly publicationReviewControl: PublicationReviewControl; 15 | 16 | getPublicationReviewControl(): PublicationReviewControl { 17 | return this.publicationReviewControl; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /libs/modulify-ui/src/lib/utils/appWithJss.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentType, useEffect } from 'react'; 2 | 3 | const SERVER_SIDE_JSS_STYLES_ID = 'server-side-jss-styles'; 4 | 5 | export const appWithJss =

(App: ComponentType

) => { 6 | return (props: P) => { 7 | useEffect(() => { 8 | const animationFrameId = requestAnimationFrame(() => { 9 | const serverStyles = globalThis.document.getElementById( 10 | SERVER_SIDE_JSS_STYLES_ID, 11 | ); 12 | if (serverStyles) { 13 | serverStyles.parentNode?.removeChild(serverStyles); 14 | } 15 | }); 16 | 17 | return () => { 18 | cancelAnimationFrame(animationFrameId); 19 | }; 20 | }, []); 21 | 22 | return ; 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/injector/dataInjectorInterface.ts: -------------------------------------------------------------------------------- 1 | import { Conversation } from '@/chat/types/chat'; 2 | import { FolderInterface } from '@/chat/types/folder'; 3 | import { Prompt } from '@/chat/types/prompt'; 4 | 5 | export interface DataInjectorInterface { 6 | createConversations( 7 | conversations: Conversation[], 8 | ...folders: FolderInterface[] 9 | ): Promise; 10 | updateConversations( 11 | conversations: Conversation[], 12 | ...folders: FolderInterface[] 13 | ): Promise; 14 | createPrompts( 15 | prompts: Prompt[], 16 | ...folders: FolderInterface[] 17 | ): Promise; 18 | updatePrompts( 19 | prompts: Prompt[], 20 | ...folders: FolderInterface[] 21 | ): Promise; 22 | deleteAllData(): Promise; 23 | } 24 | -------------------------------------------------------------------------------- /apps/custom-viewer-test/next.config.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-var-requires 4 | const { composePlugins, withNx } = require('@nx/next'); 5 | 6 | /** 7 | * @type {import('@nx/next/plugins/with-nx').WithNxOptions} 8 | **/ 9 | const nextConfig = { 10 | nx: { 11 | // Set this to true if you would like to use SVGR 12 | // See: https://github.com/gregberge/svgr 13 | svgr: false, 14 | }, 15 | webpack(config) { 16 | config.experiments = { 17 | asyncWebAssembly: true, 18 | layers: true, 19 | }; 20 | 21 | return config; 22 | }, 23 | }; 24 | 25 | const plugins = [ 26 | // Add more Next.js plugins to this list if needed. 27 | withNx, 28 | ]; 29 | 30 | module.exports = composePlugins(...plugins)(nextConfig); 31 | -------------------------------------------------------------------------------- /apps/overlay-sandbox/next.config.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | // eslint-disable-next-line @typescript-eslint/no-var-requires 4 | const { composePlugins, withNx } = require('@nx/next'); 5 | 6 | /** 7 | * @type {import('@nx/next/plugins/with-nx').WithNxOptions} 8 | **/ 9 | const nextConfig = { 10 | nx: { 11 | // Set this to true if you would like to use SVGR 12 | // See: https://github.com/gregberge/svgr 13 | svgr: false, 14 | }, 15 | webpack(config) { 16 | config.experiments = { 17 | asyncWebAssembly: true, 18 | layers: true, 19 | }; 20 | 21 | return config; 22 | }, 23 | }; 24 | 25 | const plugins = [ 26 | // Add more Next.js plugins to this list if needed. 27 | withNx, 28 | ]; 29 | 30 | module.exports = composePlugins(...plugins)(nextConfig); 31 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/conversationAssertion.ts: -------------------------------------------------------------------------------- 1 | import { SideBarConversationAssertion } from '@/src/assertions/sideBarConversationAssertion'; 2 | import { Chronology, ExpectedMessages } from '@/src/testData'; 3 | import { ConversationsTree } from '@/src/ui/webElements/entityTree'; 4 | import { expect } from '@playwright/test'; 5 | 6 | export class ConversationAssertion extends SideBarConversationAssertion { 7 | public async assertConversationInToday(conversationName: string) { 8 | const todayConversations = 9 | await this.sideBarConversationsTree.getChronologyConversations( 10 | Chronology.today, 11 | ); 12 | expect(todayConversations, ExpectedMessages.conversationOfToday).toContain( 13 | conversationName, 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/folder-plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/Publish/ReviewDot.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | 3 | interface Props { 4 | className?: string; 5 | } 6 | 7 | export function ReviewDot({ className }: Props) { 8 | return ( 9 | 10 | 11 | 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/e2e_tests.yml: -------------------------------------------------------------------------------- 1 | name: E2E tests trigger 2 | 3 | on: 4 | registry_package: 5 | 6 | jobs: 7 | e2e-tests: 8 | runs-on: ubuntu-latest 9 | if: ${{ github.event.registry_package.package_version.container_metadata.tag.name == 'development' }} 10 | steps: 11 | - name: E2E tests 12 | uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1 13 | with: 14 | token: ${{ secrets.ACTIONS_BOT_TOKEN }} 15 | repository: epam/ai-dial-ci 16 | event-type: e2e-tests-workflow 17 | client-payload: |- 18 | { 19 | "github-app": "${{github.event.repository.name}}", 20 | "github-sha": "${{github.sha}}", 21 | "gitlab-project-id": "1843" 22 | } 23 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/banner.ts: -------------------------------------------------------------------------------- 1 | import { Tags } from '@/src/ui/domData'; 2 | import { HeaderSelectors, IconSelectors } from '@/src/ui/selectors'; 3 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 4 | import { Locator, Page } from '@playwright/test'; 5 | 6 | export class Banner extends BaseElement { 7 | constructor(page: Page, parentLocator: Locator) { 8 | super(page, HeaderSelectors.banner, parentLocator); 9 | } 10 | 11 | public bannerMessage = this.getChildElementBySelector(Tags.span); 12 | public bannerMessageLink = this.bannerMessage.getChildElementBySelector( 13 | Tags.a, 14 | ); 15 | public bannerIcon = this.getChildElementBySelector(Tags.svg).getNthElement(1); 16 | public closeButton = this.getChildElementBySelector(IconSelectors.cancelIcon); 17 | } 18 | -------------------------------------------------------------------------------- /apps/chat/src/components/Files/Download.tsx: -------------------------------------------------------------------------------- 1 | import { getDownloadPath } from '@/src/utils/app/file'; 2 | import { ApiUtils } from '@/src/utils/server/api'; 3 | 4 | import { DialFile } from '@/src/types/files'; 5 | import { CustomTriggerMenuRendererProps } from '@/src/types/menu'; 6 | 7 | export function DownloadRenderer({ 8 | customTriggerData, 9 | onClick, 10 | className, 11 | Renderer, 12 | ...props 13 | }: CustomTriggerMenuRendererProps) { 14 | const file = customTriggerData as DialFile; 15 | const filePath = getDownloadPath(file); 16 | 17 | return ( 18 | 24 | 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /libs/visualizer-connector/README.md: -------------------------------------------------------------------------------- 1 | # DIAL Visualizer Connector 2 | 3 | DIAL Visualizer Connector is a library for connecting DIAL CHAT with custom visualizers - applications which could visualize some special type data (for example **plot data** for the **Plotly**). 4 | 5 | ## Public classes to use 6 | 7 | `VisualizerConnector` - class which creates iframe with provided **VisualizerConnector**, allows to interact with **Visualizer** rendered in the iframe (send data). Types for configuration options is `VisualizerConnectorOptions`. 8 | 9 | ## Prerequisites 10 | 11 | How to configure your DIAL CHAT to use **Custom Visualizers** you could find [here](../chat-visualizer-connector/README.md). 12 | 13 | At **Visualizer** side should be used [DIAL Chat VIsualizer Connector](../chat-visualizer-connector/README.md) 14 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/api/bucketApiHelper.ts: -------------------------------------------------------------------------------- 1 | import { BaseApiHelper } from './baseApiHelper'; 2 | 3 | import { API } from '@/src/testData'; 4 | import { APIRequestContext } from '@playwright/test'; 5 | 6 | export class BucketApiHelper extends BaseApiHelper { 7 | constructor(request: APIRequestContext) { 8 | super(request); 9 | } 10 | 11 | public async getBucket(): Promise<{ bucket: string; bucketJson: string }> { 12 | const response = await this.request.get(this.getHost(API.bucketHost)); 13 | if (response.status() !== 200) { 14 | throw new Error(`Failed to get bucket: ${response.status()}`); 15 | } 16 | 17 | const bucketJson = await response.text(); 18 | const { bucket } = JSON.parse(bucketJson) as { bucket: string }; 19 | 20 | return { bucket, bucketJson }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /apps/chat/src/components/Chat/ChatInput/SchemaCompareWarning.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from '@/src/hooks/useTranslation'; 2 | 3 | import { Translation } from '@/src/types/translation'; 4 | 5 | import { ErrorMessage } from '@/src/components/Common/ErrorMessage'; 6 | 7 | export const SchemaCompareWarning = () => { 8 | const { t } = useTranslation(Translation.Chat); 9 | 10 | return ( 11 |

12 |
13 | 19 |
20 |
21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/testData/index.ts: -------------------------------------------------------------------------------- 1 | export * from './expectedMessages'; 2 | export * from './expectedConstants'; 3 | export * from './conversationHistory/conversationBuilder'; 4 | export * from './conversationHistory/conversationData'; 5 | export * from './conversationHistory/folderBuilder'; 6 | export * from './prompts/promptBuilder'; 7 | export * from './prompts/promptData'; 8 | export * from './folders/folderData'; 9 | export * from './types'; 10 | export * from './publishing/publishRequestBuilder'; 11 | export * from './overlay/overlaySandboxUrls'; 12 | export * from './applications/customApplicationBuilder'; 13 | export * from './marketplace/baseUrlBuilder'; 14 | export * from './marketplace/marketplaceUrlBuilder'; 15 | export * from './marketplace/entityEditorUrlBuilder'; 16 | export * from './toolsets/toolsetBuilder'; 17 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/conversationToCompareAssertion.ts: -------------------------------------------------------------------------------- 1 | import { BaseAssertion } from '@/src/assertions/base/baseAssertion'; 2 | import { ElementState } from '@/src/testData'; 3 | import { ConversationToCompare } from '@/src/ui/webElements'; 4 | 5 | export class ConversationToCompareAssertion extends BaseAssertion { 6 | readonly conversationToCompare: ConversationToCompare; 7 | 8 | constructor(conversationToCompare: ConversationToCompare) { 9 | super(); 10 | this.conversationToCompare = conversationToCompare; 11 | } 12 | 13 | public async assertConversationToCompareState( 14 | expectedState: ElementState, 15 | expectedMessage?: string, 16 | ) { 17 | await this.assertElementState( 18 | this.conversationToCompare, 19 | expectedState, 20 | expectedMessage, 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/editInputActions.ts: -------------------------------------------------------------------------------- 1 | import { EditSelectors } from '@/src/ui/selectors/editSelectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { Locator, Page } from '@playwright/test'; 4 | 5 | export class EditInputActions extends BaseElement { 6 | constructor(page: Page, parentLocator: Locator, selector: string) { 7 | super( 8 | page, 9 | `${selector} >> ${EditSelectors.actionsContainer}`, 10 | parentLocator, 11 | ); 12 | } 13 | 14 | public tickButton = this.getChildElementBySelector(EditSelectors.confirmEdit); 15 | 16 | public async clickTickButton() { 17 | await this.tickButton.click(); 18 | } 19 | 20 | public async clickCancelButton() { 21 | await this.getChildElementBySelector(EditSelectors.cancelEdit).click(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/utils/applicationsUtil.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApiApplicationTypeSchema, 3 | ApplicationTypeSchemaProperties, 4 | } from '@/chat/types/application-type-schema'; 5 | import { EntityEditorAppTypes } from '@/src/testData'; 6 | 7 | export class ApplicationsUtil { 8 | public static getApplicationSchemas() { 9 | return JSON.parse(process.env.APP_SCHEMAS!) as ApiApplicationTypeSchema[]; 10 | } 11 | 12 | public static getAppSchemaByName(appName: EntityEditorAppTypes): string { 13 | const app = ApplicationsUtil.getApplicationSchemas().find( 14 | (app) => 15 | app[ApplicationTypeSchemaProperties.applicationTypeDisplayName] === 16 | appName, 17 | ); 18 | if (!app) { 19 | throw new Error('External applications schema is not found!'); 20 | } 21 | return app.$id; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/chat-e2e/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:playwright/recommended", "../../.eslintrc.json"], 3 | "plugins": ["playwright"], 4 | "settings": { 5 | "playwright": { 6 | "globalAliases": { 7 | "test": [ 8 | "base", 9 | "dialTest", 10 | "dialSharedWithMeTest", 11 | "dialAdminTest", 12 | "dialOverlayTest" 13 | ] 14 | } 15 | } 16 | }, 17 | "overrides": [ 18 | { 19 | "files": ["src/**/*.{ts,js,tsx,jsx}"], 20 | "rules": { 21 | "playwright/no-conditional-in-test": "off", 22 | "playwright/no-conditional-expect": "off", 23 | "playwright/no-skipped-test": "off", 24 | "playwright/expect-expect": "off", 25 | "@typescript-eslint/no-non-null-assertion": "off" 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/baseLayoutContainer.ts: -------------------------------------------------------------------------------- 1 | import { layoutContainer } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { NavigationPanel } from '@/src/ui/webElements/navigationPanel'; 4 | import { Page } from '@playwright/test'; 5 | 6 | export abstract class BaseLayoutContainer< 7 | T extends BaseElement, 8 | > extends BaseElement { 9 | constructor(page: Page) { 10 | super(page, layoutContainer); 11 | } 12 | 13 | protected header!: T; 14 | protected navigationPanel!: NavigationPanel; 15 | 16 | abstract getHeader(): T; 17 | 18 | getNavigationPanel(): NavigationPanel { 19 | if (!this.navigationPanel) { 20 | this.navigationPanel = new NavigationPanel(this.page, this.rootLocator); 21 | } 22 | return this.navigationPanel; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityEditor/base/entitySettings/entityEditorEntitySettingsPreviewHeader.ts: -------------------------------------------------------------------------------- 1 | import { 2 | EntityEditorEntitySettingsPreviewSelectors, 3 | IconSelectors, 4 | } from '@/src/ui/selectors'; 5 | import { BaseElement } from '@/src/ui/webElements'; 6 | import { Locator, Page } from '@playwright/test'; 7 | 8 | export class EntityEditorEntitySettingsPreviewHeader extends BaseElement { 9 | constructor(page: Page, parentLocator: Locator) { 10 | super( 11 | page, 12 | EntityEditorEntitySettingsPreviewSelectors.header, 13 | parentLocator, 14 | ); 15 | } 16 | 17 | protected expandIcon = this.getChildElementBySelector( 18 | IconSelectors.arrowsMaximizeIcon, 19 | ); 20 | protected hideIcon = this.getChildElementBySelector( 21 | IconSelectors.arrowsMinimizeIcon, 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/selectors/loginSelectors.ts: -------------------------------------------------------------------------------- 1 | import { AuthProvider } from '@/src/testData'; 2 | 3 | export const Auth0Selectors = { 4 | auth0Container: '.auth0-lock-widget-container', 5 | ssoSignIn: (authProvider: AuthProvider) => `[data-qa="${authProvider}"]`, 6 | username: '[name="email"]', 7 | password: '[name="password"]', 8 | login: '[name="submit"]', 9 | }; 10 | 11 | export const KeycloakSelectors = { 12 | keycloakContainer: '[id="kc-form"]', 13 | email: '#username', 14 | password: '#password', 15 | nextButton: '[value="Next"]', 16 | signiInButton: '[type="submit"]', 17 | }; 18 | 19 | export const AzureADSelectors = { 20 | azureADContainer: '#lightbox', 21 | email: '[name="loginfmt"]', 22 | password: '[name="passwd"]', 23 | nextButton: '[value="Next"]', 24 | signiInButton: '[value="Sign in"]', 25 | }; 26 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/auth0.ts: -------------------------------------------------------------------------------- 1 | import { Auth0Selectors } from '@/src/ui/selectors'; 2 | import { BaseElement } from '@/src/ui/webElements/baseElement'; 3 | import { Page } from '@playwright/test'; 4 | 5 | export class Auth0 extends BaseElement { 6 | constructor(page: Page) { 7 | super(page, Auth0Selectors.auth0Container); 8 | } 9 | 10 | public usernameInput = this.getChildElementBySelector( 11 | Auth0Selectors.username, 12 | ); 13 | public passwordInput = this.getChildElementBySelector( 14 | Auth0Selectors.password, 15 | ); 16 | public loginButton = this.getChildElementBySelector(Auth0Selectors.login); 17 | 18 | public async setCredentials(username: string, password: string) { 19 | await this.usernameInput.fillInInput(username); 20 | await this.passwordInput.fillInInput(password); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/utils/themesUtil.ts: -------------------------------------------------------------------------------- 1 | import { Theme, ThemesImages } from '@/chat/types/themes'; 2 | import { ThemeId } from '@/src/testData'; 3 | import { ThemeColorAttributes } from '@/src/ui/domData'; 4 | import tinycolor from 'tinycolor2'; 5 | 6 | export class ThemesUtil { 7 | public static getThemes() { 8 | return JSON.parse(process.env.THEMES!).themes as Theme[]; 9 | } 10 | 11 | public static getImages() { 12 | return JSON.parse(process.env.THEMES!).images as ThemesImages; 13 | } 14 | 15 | public static getRgbColorByKey(key: ThemeColorAttributes, themeId?: ThemeId) { 16 | const allThemes = this.getThemes(); 17 | const theme = themeId 18 | ? allThemes.find((t) => t.id === themeId) 19 | : allThemes[0]; 20 | const hex = theme?.colors[key]; 21 | return tinycolor(hex).toRgbString(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/chat/src/constants/default-server-settings.ts: -------------------------------------------------------------------------------- 1 | import { FALLBACK_MODEL_ID } from './default-ui-settings'; 2 | 3 | export const DIAL_API_HOST = process.env.DIAL_API_HOST; 4 | 5 | export const DIAL_API_VERSION = 6 | process.env.DIAL_API_VERSION || '2025-01-01-preview'; 7 | 8 | export const DEFAULT_MODEL_ID = process.env.DEFAULT_MODEL || FALLBACK_MODEL_ID; 9 | 10 | export const MAX_PROMPT_TOKENS_DEFAULT_PERCENT = process.env 11 | .MAX_PROMPT_TOKENS_DEFAULT_PERCENT 12 | ? parseInt(process.env.MAX_PROMPT_TOKENS_DEFAULT_PERCENT, 10) 13 | : 75; 14 | 15 | export const MAX_PROMPT_TOKENS_DEFAULT_VALUE = process.env 16 | .MAX_PROMPT_TOKENS_DEFAULT_VALUE 17 | ? parseInt(process.env.MAX_PROMPT_TOKENS_DEFAULT_VALUE, 10) 18 | : 2000; 19 | 20 | export const DEFAULT_SYSTEM_PROMPT = 21 | process.env.NEXT_PUBLIC_DEFAULT_SYSTEM_PROMPT ?? ''; 22 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityEditor/customApp/customAppEditorAppSettingsPreview.ts: -------------------------------------------------------------------------------- 1 | import { CustomAppEditorAppSettingsPreviewBody } from '@/src/ui/webElements'; 2 | import { EntityEditorEntitySettingsPreview } from '@/src/ui/webElements'; 3 | 4 | export class CustomAppEditorAppSettingsPreview extends EntityEditorEntitySettingsPreview { 5 | protected entityEditorEntitySettingsPreviewBody!: CustomAppEditorAppSettingsPreviewBody; 6 | 7 | getEntityEditorEntitySettingsPreviewBody(): CustomAppEditorAppSettingsPreviewBody { 8 | if (!this.entityEditorEntitySettingsPreviewBody) { 9 | this.entityEditorEntitySettingsPreviewBody = 10 | new CustomAppEditorAppSettingsPreviewBody(this.page, this.rootLocator); 11 | } 12 | return this.entityEditorEntitySettingsPreviewBody; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/chat/src/store/application/applications.types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApplicationLogsType, 3 | CustomApplicationModel, 4 | } from '@/src/types/applications'; 5 | import { FolderInterface } from '@/src/types/folder'; 6 | import { MarketplaceEditorSteps } from '@/src/types/marketplace'; 7 | 8 | import { UploadStatus } from '@epam/ai-dial-shared'; 9 | 10 | export interface ApplicationState { 11 | initialized: boolean; 12 | appLoading: UploadStatus; 13 | logsLoadingStatus: UploadStatus; 14 | appDetails: CustomApplicationModel | undefined; 15 | appLogs: ApplicationLogsType | undefined; 16 | publicFolders: FolderInterface[]; 17 | 18 | returnConversationIds?: string[]; 19 | selectedWidget?: string; 20 | 21 | logsEntityId: string | undefined; 22 | editorStep: MarketplaceEditorSteps; 23 | shouldTriggerEditorAutoUpdate: boolean; 24 | } 25 | -------------------------------------------------------------------------------- /apps/chat/src/utils/app/sidebar.ts: -------------------------------------------------------------------------------- 1 | import { CENTRAL_CHAT_MIN_WIDTH } from '@/src/constants/chat'; 2 | import { SIDEBAR_MIN_WIDTH } from '@/src/constants/default-ui-settings'; 3 | 4 | export const centralChatWidth = ({ 5 | oppositeSidebarWidth = SIDEBAR_MIN_WIDTH, 6 | windowWidth, 7 | currentSidebarWidth = SIDEBAR_MIN_WIDTH, 8 | }: { 9 | oppositeSidebarWidth?: number; 10 | windowWidth: number; 11 | currentSidebarWidth?: number; 12 | }) => windowWidth - currentSidebarWidth - oppositeSidebarWidth; 13 | 14 | export const getNewSidebarWidth = ({ 15 | windowWidth, 16 | centralChatMinWidth = CENTRAL_CHAT_MIN_WIDTH, 17 | oppositeSidebarWidth = SIDEBAR_MIN_WIDTH, 18 | }: { 19 | windowWidth: number; 20 | centralChatMinWidth?: number; 21 | oppositeSidebarWidth?: number; 22 | }) => windowWidth - oppositeSidebarWidth - centralChatMinWidth; 23 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/accountSettingsAssertion.ts: -------------------------------------------------------------------------------- 1 | import { ElementCaretState, ExpectedMessages } from '@/src/testData'; 2 | import { AccountSettings } from '@/src/ui/webElements'; 3 | import { expect } from '@playwright/test'; 4 | 5 | export class AccountSettingsAssertion { 6 | readonly accountSettings: AccountSettings; 7 | 8 | constructor(accountSettings: AccountSettings) { 9 | this.accountSettings = accountSettings; 10 | } 11 | 12 | public async assertCaretState(expectedState: ElementCaretState) { 13 | const caret = this.accountSettings.accountSettingsCaret.getElementLocator(); 14 | expectedState === 'expanded' 15 | ? await expect.soft(caret, ExpectedMessages.caretIsExpanded).toBeVisible() 16 | : await expect 17 | .soft(caret, ExpectedMessages.caretIsCollapsed) 18 | .toBeHidden(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/ui/webElements/entityTree/publication/publishPromptsTree.ts: -------------------------------------------------------------------------------- 1 | import { 2 | EntitySelectors, 3 | IconSelectors, 4 | PublishingTreeSelectors, 5 | } from '@/src/ui/selectors'; 6 | import { PublishEntitiesTree } from '@/src/ui/webElements/entityTree/publishEntitiesTree'; 7 | import { Locator, Page } from '@playwright/test'; 8 | 9 | export class PublishPromptsTree extends PublishEntitiesTree { 10 | constructor(page: Page, parentLocator: Locator) { 11 | super( 12 | page, 13 | parentLocator, 14 | PublishingTreeSelectors.promptsTree, 15 | EntitySelectors.prompt, 16 | ); 17 | } 18 | 19 | public promptIcon = ( 20 | name: string, 21 | indexOrOptions?: number | { exactMatch: boolean; index?: number }, 22 | ) => 23 | this.getTreeEntity(name, indexOrOptions).locator(IconSelectors.promptIcon); 24 | } 25 | -------------------------------------------------------------------------------- /apps/chat-e2e/src/assertions/selectFolderModalAssertion.ts: -------------------------------------------------------------------------------- 1 | import { BaseAssertion } from '@/src/assertions/base/baseAssertion'; 2 | import { ExpectedMessages } from '@/src/testData'; 3 | import { Attributes } from '@/src/ui/domData'; 4 | import { SelectFolderModal } from '@/src/ui/webElements'; 5 | 6 | export class SelectFolderModalAssertion extends BaseAssertion { 7 | readonly selectFolderModal: SelectFolderModal; 8 | 9 | constructor(selectFolderModal: SelectFolderModal) { 10 | super(); 11 | this.selectFolderModal = selectFolderModal; 12 | } 13 | 14 | public async assertSectionSelectedState(isSelected: boolean) { 15 | await super.assertElementAttribute( 16 | this.selectFolderModal.rootFolder, 17 | Attributes.ariaSelected, 18 | String(isSelected), 19 | ExpectedMessages.folderIsHighlighted, 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /apps/chat/public/images/icons/unpublish.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /apps/chat/src/components/Common/ScreenRender.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentType } from 'react'; 2 | 3 | import { useScreenState } from '@/src/hooks/useScreenState'; 4 | 5 | import { ScreenState } from '@/src/types/common'; 6 | 7 | import { getComponentDisplayName } from './RenderWhen'; 8 | 9 | export function withRenderForScreen(screenStates: ScreenState[]) { 10 | return function (WrappedComponent: ComponentType) { 11 | const ComponentWithRenderForScreen = (props: T) => { 12 | const screenState = useScreenState(); 13 | return screenStates.includes(screenState) ? ( 14 | 15 | ) : null; 16 | }; 17 | 18 | ComponentWithRenderForScreen.displayName = `withRenderForScreen(${getComponentDisplayName(WrappedComponent)})`; 19 | 20 | return ComponentWithRenderForScreen; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /apps/chat/src/components/Title.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | import { useRouter } from 'next/router'; 3 | 4 | import { useTranslation } from '@/src/hooks/useTranslation'; 5 | 6 | import { getPageName } from '@/src/utils/app/route'; 7 | 8 | import { Translation } from '@/src/types/translation'; 9 | 10 | import { SettingsState } from '@/src/store/settings/settings.types'; 11 | 12 | export function Title({ settings }: { settings?: SettingsState }) { 13 | const router = useRouter(); 14 | const { t } = useTranslation(Translation.Common); 15 | const pageName = t(getPageName(router)); 16 | 17 | return ( 18 | 19 | 20 | {[settings?.appName, pageName].filter(Boolean).join(' : ')} 21 | 22 | 23 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /libs/shared/src/types/overlay/events.ts: -------------------------------------------------------------------------------- 1 | import { Message, Playback } from '../chat'; 2 | 3 | export interface SelectedConversationLoadedEventResponse { 4 | selectedConversationIds: string[]; 5 | } 6 | export interface MessageCustomButtonEventResponse { 7 | eventName: keyof WindowEventMap; 8 | buttonKey: string; 9 | messageIndex: number; 10 | } 11 | export interface EditMessageEventResponse { 12 | editedMessage: Message; 13 | index: number; 14 | convId: string; 15 | } 16 | export interface DeleteMessageEventResponse { 17 | index: number; 18 | } 19 | export interface PrevMessagePlaybackEventResponse { 20 | newActiveIndex: number; 21 | updatedMessages: Message[]; 22 | playbackState: Playback; 23 | } 24 | export interface NextMessagePlaybackEventResponse { 25 | newActiveIndex: number; 26 | updatedMessages: Message[]; 27 | playbackState: Playback; 28 | } 29 | --------------------------------------------------------------------------------