/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */ import * as CLM from '@conversationlearner/models' ; import * as ClientFactory from '../services/clientFactory' ; import { ActionObject , ErrorType } from '../types' ; import { AT } from '../types/ActionTypes' ; import { Dispatch } from 'redux' ; import { setErrorDisplay } from './displayActions' ; import { AxiosError } from 'axios' ; import { fetchAllTrainDialogsThunkAsync } from './trainActions' ; import { EntityLabelConflictError } from '../types/errors' ; import { fetchApplicationTrainingStatusThunkAsync } from './appActions' ; const createTeachSessionAsync = ( ) : ActionObject => ( { type : AT . CREATE_TEACH_SESSION_ASYNC } ) ; const createTeachSessionRejected = ( ) : ActionObject => ( { type : AT . CREATE_TEACH_SESSION_REJECTED } ) ; const createTeachSessionFulfilled = ( teachResponse , memories ) : ActionObject => ( { type : AT . CREATE_TEACH_SESSION_FULFILLED , teachSession : teachResponse as CLM . Teach , memories } ) ; export const createTeachSessionThunkAsync = ( appId , initialEntityMap = null ) => { return async ( dispatch ) => { const clClient = ClientFactory . getInstance ( AT . CREATE_TEACH_SESSION_ASYNC ) ; dispatch ( createTeachSessionAsync ( ) ) ; try { const initialFilledEntities = initialEntityMap ? initialEntityMap . FilledEntities ( ) : [ ] ; const initialMemory = initialEntityMap ? initialEntityMap . ToMemory ( ) : [ ] ; const teachResponse = await clClient . teachSessionCreate ( appId , initialFilledEntities ) ; dispatch ( createTeachSessionFulfilled ( teachResponse , initialMemory ) ) ; return teachResponse ; } catch ( e ) { const error = e as AxiosError ; dispatch ( setErrorDisplay ( ErrorType . Error , error . message , error . response ? JSON . stringify ( error . response , null , '  ' ) : "" , AT . CREATE_TEACH_SESSION_ASYNC ) ) ; dispatch ( createTeachSessionRejected ( ) ) ; throw error ; } } ; } ; const createTeachSessionFromTrainDialogAsync = ( appId , trainDialog , userName , userId ) : ActionObject => { return { type : AT . CREATE_TEACH_SESSION_FROMTRAINDIALOG_ASYNC , appId : appId , userName : userName , userId : userId , trainDialog : trainDialog } ; } ; const createTeachSessionFromTrainDialogFulfilled = ( teachWithActivities ) : ActionObject => { return { type : AT . CREATE_TEACH_SESSION_FROMTRAINDIALOG_FULFILLED , teachWithActivities , } ; } ; const createTeachSessionFromTrainDialogRejected = ( ) : ActionObject => ( { type : AT . CREATE_TEACH_SESSION_FROMTRAINDIALOG_REJECTED } ) ; export const createTeachSessionFromTrainDialogThunkAsync = ( app , trainDialog , userName , userId , initialUserInput , filteredDialogId ) => { return async ( dispatch ) => { const clClient = ClientFactory . getInstance ( AT . CREATE_TEACH_SESSION_FROMTRAINDIALOG_ASYNC ) ; dispatch ( createTeachSessionFromTrainDialogAsync ( app . appId , trainDialog , userName , userId ) ) ; try { const teachWithActivities = await clClient . teachSessionFromTrainDialog ( app . appId , trainDialog , initialUserInput , userName , userId , filteredDialogId ) ; dispatch ( createTeachSessionFromTrainDialogFulfilled ( teachWithActivities ) ) ; return teachWithActivities ; } catch ( e ) { dispatch ( createTeachSessionFromTrainDialogRejected ( ) ) ; const error = e as AxiosError ; if ( error . response ?. status === 409 ) { const textVariations = error . response . data . reason ; const conflictError = new EntityLabelConflictError ( error . message , textVariations ) ; throw conflictError ; } dispatch ( setErrorDisplay ( ErrorType . Error , error . message , error . response ? JSON . stringify ( error . response , null , '  ' ) : "" , AT . CREATE_TEACH_SESSION_FROMTRAINDIALOG_ASYNC ) ) ; throw error ; } } ; } ; const deleteTeachSessionAsync = ( teachSession , appId , save ) : ActionObject => { return { type : AT . DELETE_TEACH_SESSION_ASYNC , teachSession : teachSession , appId : appId , save : save } ; } ; const deleteTeachSessionFulfilled = ( teachSession , newTrainDialog , sourceTrainDialogId ) : ActionObject => { return { type : AT . DELETE_TEACH_SESSION_FULFILLED , teachSessionGUID : teachSession . teachId , newTrainDialog , sourceTrainDialogId } ; } ; const updateSourceLogDialog = ( trainDialogId , sourceLogDialogId ) : ActionObject => { return { type : AT . UPDATE_SOURCE_LOG_DIALOG , trainDialogId , sourceLogDialogId } ; } ; export const clearTeachSession = ( ) : ActionObject => { return { type : AT . CLEAR_TEACH_SESSION } ; } ; export const deleteTeachSessionThunkAsync = ( teachSession , app , save = false , sourceLogDialogId = null , sourceTrainDialogId = null ) => { return async ( dispatch ) => { dispatch ( deleteTeachSessionAsync ( teachSession , app . appId , save ) ) ; const clClient = ClientFactory . getInstance ( AT . DELETE_TEACH_SESSION_ASYNC ) ; try { await clClient . teachSessionDelete ( app . appId , teachSession , save ) ; if ( sourceLogDialogId ) { dispatch ( updateSourceLogDialog ( teachSession . trainDialogId , sourceLogDialogId ) ) ; } const newTrainDialog = save ? await clClient . trainDialog ( app . appId , teachSession . trainDialogId ) : null ; dispatch ( deleteTeachSessionFulfilled ( teachSession , newTrainDialog , sourceTrainDialogId ) ) ; if ( save ) { void dispatch ( fetchApplicationTrainingStatusThunkAsync ( app . appId ) ) ; } return newTrainDialog ; } catch ( e ) { const error = e as AxiosError ; dispatch ( clearTeachSession ( ) ) ; dispatch ( setErrorDisplay ( ErrorType . Error , error . message , error . response ? JSON . stringify ( error . response , null , '  ' ) : "" , AT . CREATE_TRAIN_DIALOG_ASYNC ) ) ; void dispatch ( fetchAllTrainDialogsThunkAsync ( app . appId ) ) ; throw error ; } } ; } ; const deleteMemoryAsync = ( key , currentAppId ) : ActionObject => { return { type : AT . DELETE_MEMORY_ASYNC , key : key , appId : currentAppId } ; } ; const deleteMemoryFulfilled = ( ) : ActionObject => { return { type : AT . DELETE_MEMORY_FULFILLED } ; } ; export const deleteMemoryThunkAsync = ( key , currentAppId ) => { return async ( dispatch ) => { dispatch ( deleteMemoryAsync ( key , currentAppId ) ) ; const clClient = ClientFactory . getInstance ( AT . DELETE_MEMORY_ASYNC ) ; try { await clClient . memoryDelete ( currentAppId ) ; dispatch ( deleteMemoryFulfilled ( ) ) ; return true ; } catch ( e ) { const error = e as AxiosError ; dispatch ( setErrorDisplay ( ErrorType . Error , error . message , error . response ? JSON . stringify ( error . response , null , '  ' ) : "" , AT . DELETE_MEMORY_ASYNC ) ) ; return false ; } } ; } ; const runExtractorAsync = ( appId , extractType , sessionId , turnIndex , userInput ) : ActionObject => { return { type : AT . RUN_EXTRACTOR_ASYNC , appId : appId , extractType : extractType , sessionId : sessionId , turnIndex : turnIndex , userInput : userInput } ; } ; const runExtractorFulfilled = ( appId , sessionId , uiExtractResponse ) : ActionObject => { return { type : AT . RUN_EXTRACTOR_FULFILLED , appId : appId , sessionId : sessionId , uiExtractResponse : uiExtractResponse } ; } ; export const runExtractorThunkAsync = ( appId , extractType , sessionId , turnIndex , userInput , filteredDialog ) => { return async ( dispatch ) => { const clClient = ClientFactory . getInstance ( AT . RUN_EXTRACTOR_ASYNC ) ; dispatch ( runExtractorAsync ( appId , extractType , sessionId , turnIndex , userInput ) ) ; try { let uiExtractResponse = null ; switch ( extractType ) { case CLM . DialogType . TEACH : uiExtractResponse = await clClient . teachSessionAddExtractStep ( appId , sessionId , userInput , filteredDialog ) ; break ; case CLM . DialogType . TRAINDIALOG : if ( turnIndex === null ) { throw new Error ( `Run extractor was called for a train dialog, but turnIndex was null. This should not be possible. Please open an issue.` ) ; } uiExtractResponse = await clClient . trainDialogsUpdateExtractStep ( appId , sessionId , turnIndex , userInput ) ; break ; case CLM . DialogType . LOGDIALOG : if ( turnIndex === null ) { throw new Error ( `Run extractor was called for a log dialog, but turnIndex was null. This should not be possible. Please open an issue.` ) ; } uiExtractResponse = await clClient . logDialogsUpdateExtractStep ( appId , sessionId , turnIndex , userInput ) ; break ; default : throw new Error ( `Could not handle unknown extract type: ${ extractType }` ) ; } dispatch ( runExtractorFulfilled ( appId , sessionId , uiExtractResponse ) ) ; return uiExtractResponse ; } catch ( e ) { const error = e as AxiosError ; dispatch ( setErrorDisplay ( ErrorType . Error , error . message , error . response ? JSON . stringify ( error . response , null , '  ' ) : "" , AT . RUN_EXTRACTOR_ASYNC ) ) ; throw error ; } } ; } ; export const updateExtractResponse = ( extractResponse ) : ActionObject => { return { type : AT . UPDATE_EXTRACT_RESPONSE , extractResponse : extractResponse } ; } ; export const removeExtractResponse = ( extractResponse ) : ActionObject => { return { type : AT . REMOVE_EXTRACT_RESPONSE , extractResponse : extractResponse } ; } ; export const clearExtractResponses = ( ) : ActionObject => { return { type : AT . CLEAR_EXTRACT_RESPONSES } ; } ; export const clearExtractConflict = ( ) : ActionObject => { return { type : AT . CLEAR_EXTRACT_CONFLICT } ; } ; const getScoresAsync = ( key , appId , sessionId , scoreInput ) : ActionObject => ( { type : AT . GET_SCORES_ASYNC , key , appId , sessionId , scoreInput } ) ; const getScoresFulfilled = ( key , appId , sessionId , uiScoreResponse ) : ActionObject => ( { type : AT . GET_SCORES_FULFILLED , key , appId , sessionId , uiScoreResponse , } ) ; export const getScoresThunkAsync = ( key , appId , sessionId , scoreInput ) => { return async ( dispatch ) => { const clClient = ClientFactory . getInstance ( AT . GET_SCORES_ASYNC ) ; dispatch ( getScoresAsync ( key , appId , sessionId , scoreInput ) ) ; try { const uiScoreResponse = await clClient . teachSessionRescore ( appId , sessionId , scoreInput ) ; dispatch ( getScoresFulfilled ( key , appId , sessionId , uiScoreResponse ) ) ; return uiScoreResponse ; } catch ( e ) { const error = e as AxiosError ; dispatch ( setErrorDisplay ( ErrorType . Error , error . message , error . response ? JSON . stringify ( error . response , null , '  ' ) : "" , AT . GET_SCORES_ASYNC ) ) ; throw error ; } } ; } ; const runScorerAsync = ( key , appId , teachId , uiScoreInput ) : ActionObject => { return { type : AT . RUN_SCORER_ASYNC , key : key , appId : appId , sessionId : teachId , uiScoreInput : uiScoreInput } ; } ; const runScorerFulfilled = ( key , appId , teachId , uiScoreResponse ) : ActionObject => { return { type : AT . RUN_SCORER_FULFILLED , key , appId , sessionId : teachId , uiScoreResponse } ; } ; export const runScorerThunkAsync = ( key , appId , teachId , uiScoreInput ) => { return async ( dispatch ) => { const clClient = ClientFactory . getInstance ( AT . RUN_SCORER_ASYNC ) ; dispatch ( runScorerAsync ( key , appId , teachId , uiScoreInput ) ) ; try { const uiScoreResponse = await clClient . teachSessionUpdateScorerStep ( appId , teachId , uiScoreInput ) ; dispatch ( runScorerFulfilled ( key , appId , teachId , uiScoreResponse ) ) ; return uiScoreResponse ; } catch ( e ) { const error = e as AxiosError ; dispatch ( setErrorDisplay ( ErrorType . Error , error . message , error . response ? JSON . stringify ( error . response , null , '  ' ) : "" , AT . RUN_SCORER_ASYNC ) ) ; throw error ; } } ; } ; const postScorerFeedbackAsync = ( key , appId , teachId , uiTrainScorerStep , waitForUser , uiScoreInput ) : ActionObject => { return { type : AT . POST_SCORE_FEEDBACK_ASYNC , key : key , appId : appId , sessionId : teachId , uiTrainScorerStep : uiTrainScorerStep , waitForUser : waitForUser , uiScoreInput : uiScoreInput } ; } ; const postScorerFeedbackFulfilled = ( key , appId , teachId , dialogMode , uiPostScoreResponse , uiScoreInput ) : ActionObject => { return { type : AT . POST_SCORE_FEEDBACK_FULFILLED , key : key , appId : appId , sessionId : teachId , dialogMode : dialogMode , uiPostScoreResponse : uiPostScoreResponse , uiScoreInput : uiScoreInput } ; } ; export const postScorerFeedbackThunkAsync = ( key , appId , teachId , uiTrainScorerStep , waitForUser , uiScoreInput ) => { return async ( dispatch ) => { const clClient = ClientFactory . getInstance ( AT . POST_SCORE_FEEDBACK_ASYNC ) ; dispatch ( postScorerFeedbackAsync ( key , appId , teachId , uiTrainScorerStep , waitForUser , uiScoreInput ) ) ; try { const uiPostScoreResponse = await clClient . teachSessionAddScorerStep ( appId , teachId , uiTrainScorerStep ) ; if ( ! waitForUser ) { uiScoreInput . extractResponse . predictedEntities = [ ] ; dispatch ( postScorerFeedbackFulfilled ( key , appId , teachId , CLM . DialogMode . Scorer , uiPostScoreResponse , uiScoreInput ) ) ; } else { const dialogMode = uiPostScoreResponse . isEndTask ? CLM . DialogMode . EndSession : CLM . DialogMode . Wait ; dispatch ( postScorerFeedbackFulfilled ( key , appId , teachId , dialogMode , uiPostScoreResponse , null ) ) ; } return uiPostScoreResponse ; } catch ( e ) { const error = e as AxiosError ; dispatch ( setErrorDisplay ( ErrorType . Error , error . message , error . response ? JSON . stringify ( error . response , null , '  ' ) : "" , AT . POST_SCORE_FEEDBACK_ASYNC ) ) ; throw error ; } } ; } ; export const toggleAutoTeach = ( autoTeach ) : ActionObject => { return { type : AT . TOGGLE_AUTO_TEACH , autoTeach : autoTeach } ; } ;