messagesStack: excludeSystemMessages()

in apps/chat/src/store/conversations/conversations.epics.ts [625:825]


          messagesStack: excludeSystemMessages(conversation.messages),
          activePlaybackIndex: 0,
          isPlayback: true,
        },
        isReplay: false,
        isPlayback: true,
      });

      return of(
        ConversationsActions.saveNewConversation({
          newConversation,
        }),
      );
    }),
  );

const duplicateConversationEpic: AppEpic = (action$, state$) =>
  action$.pipe(
    filter(ConversationsActions.duplicateConversation.match),
    concatMap(({ payload }) =>
      forkJoin({
        conversation: getOrUploadConversation(payload, state$.value).pipe(
          map((data) => data.conversation),
        ),
      }),
    ),
    concatMap(({ conversation }) => {
      if (!conversation) {
        return of(
          UIActions.showErrorToast(
            translate(
              'It looks like this conversation has been deleted. Please reload the page',
            ),
          ),
        );
      }

      const conversations = ConversationsSelectors.selectConversations(
        state$.value,
      );
      const conversationFolderId = isEntityIdExternal(conversation)
        ? getConversationRootId() // duplicate external entities in the root only
        : conversation.folderId;

      const newConversation: Conversation = regenerateConversationId({
        ...omit(conversation, ['publicationInfo']),
        ...resetShareEntity,
        folderId: conversationFolderId,
        name: generateNextName(
          DEFAULT_CONVERSATION_NAME,
          conversation.name,
          conversations.filter((c) => c.folderId === conversationFolderId), // only root conversations for external entities
        ),
        lastActivityDate: Date.now(),
      });

      return concat(
        // optimistic update to reserve conversation id
        of(
          ConversationsActions.addConversations({
            conversations: [newConversation],
          }),
        ),
        of(
          ConversationsActions.saveNewConversation({
            newConversation,
            selectedIdToReplaceWithNewOne: conversation.id,
          }),
        ),
      );
    }),
  );

const createNewConversationsSuccessEpic: AppEpic = (action$) =>
  action$.pipe(
    filter(ConversationsActions.createNewConversations.match),
    switchMap(() => of(ConversationsActions.resetChosenConversations())),
  );

const saveNewConversationEpic: AppEpic = (action$) =>
  action$.pipe(
    filter(ConversationsActions.saveNewConversation.match),
    mergeMap(({ payload }) =>
      ConversationService.createConversation(payload.newConversation).pipe(
        switchMap(() =>
          of(ConversationsActions.saveNewConversationSuccess(payload)),
        ),
        catchError((err) => {
          console.error(err);
          return of(
            UIActions.showErrorToast(
              translate(
                'An error occurred while saving the conversation. Most likely the conversation already exists. Please refresh the page.',
              ),
            ),
          );
        }),
      ),
    ),
  );

const deleteFolderEpic: AppEpic = (action$, state$) =>
  action$.pipe(
    filter(ConversationsActions.deleteFolder.match),
    switchMap(({ payload }) =>
      forkJoin({
        folderId: of(payload.folderId),
        conversations: ConversationService.getConversations(
          payload.folderId,
          true,
        ).pipe(
          catchError((err) => {
            console.error('Error during delete folder:', err);
            return of([]);
          }),
        ),
        folders: of(ConversationsSelectors.selectFolders(state$.value)),
      }),
    ),
    switchMap(({ folderId, conversations, folders }) => {
      const actions: Observable<AnyAction>[] = [];

      const localConversations =
        ConversationsSelectors.selectLocalConversations(state$.value); // TODO: remove in https://github.com/epam/ai-dial-chat/issues/2651

      const conversationIds = [...conversations, ...localConversations].map(
        (conv) => conv.id,
      );

      if (conversationIds.length) {
        actions.push(
          of(ConversationsActions.deleteConversations({ conversationIds })),
        );
      } else
        actions.push(
          of(
            ConversationsActions.deleteConversationsComplete({
              conversationIds: new Set([]),
            }),
          ),
        );

      return concat(
        of(
          ConversationsActions.setFolders({
            folders: folders.filter(
              (folder) =>
                folder.id !== folderId && !folder.id.startsWith(`${folderId}/`),
            ),
          }),
        ),
        ...actions,
      );
    }),
  );

const updateFolderEpic: AppEpic = (action$, state$) =>
  action$.pipe(
    filter(ConversationsActions.updateFolder.match),
    switchMap(({ payload }) => {
      const folder = getFolderFromId(payload.folderId, FolderType.Chat);
      const newFolder = addGeneratedFolderId({ ...folder, ...payload.values });

      if (payload.folderId === newFolder.id) {
        return EMPTY;
      }

      return ConversationService.getConversations(payload.folderId, true).pipe(
        switchMap((conversations) => {
          const updateFolderId = updateMovedFolderId.bind(
            null,
            payload.folderId,
            newFolder.id,
          );
          const updateEntityId = updateMovedEntityId.bind(
            null,
            payload.folderId,
            newFolder.id,
          );

          const folders = ConversationsSelectors.selectFolders(state$.value);
          const allConversations = ConversationsSelectors.selectConversations(
            state$.value,
          );
          const openedFoldersIds = UISelectors.selectOpenedFoldersIds(
            FeatureType.Chat,
          )(state$.value);
          const selectedConversationsIds =
            ConversationsSelectors.selectSelectedConversationsIds(state$.value);

          const { updatedFolders, updatedOpenedFoldersIds } =
            updateEntitiesFoldersAndIds(
              conversations,
              folders,
              updateFolderId,
              openedFoldersIds,
            );

          const updatedConversations = combineEntities(
            allConversations.map((conv) =>
              regenerateConversationId({