2022-11-29 10:02:40 +01:00
|
|
|
import {
|
2023-02-19 09:53:57 +01:00
|
|
|
BubbleBlock,
|
|
|
|
|
BubbleBlockType,
|
2022-11-29 10:02:40 +01:00
|
|
|
ChatReply,
|
|
|
|
|
Group,
|
2022-12-22 17:02:34 +01:00
|
|
|
InputBlock,
|
|
|
|
|
InputBlockType,
|
|
|
|
|
RuntimeOptions,
|
2022-11-29 10:02:40 +01:00
|
|
|
SessionState,
|
2023-03-15 08:35:16 +01:00
|
|
|
} from '@typebot.io/schemas'
|
2022-11-29 10:02:40 +01:00
|
|
|
import {
|
|
|
|
|
isBubbleBlock,
|
2022-12-22 17:02:34 +01:00
|
|
|
isDefined,
|
2022-11-29 10:02:40 +01:00
|
|
|
isInputBlock,
|
|
|
|
|
isIntegrationBlock,
|
|
|
|
|
isLogicBlock,
|
2023-03-15 08:35:16 +01:00
|
|
|
} from '@typebot.io/lib'
|
2022-11-29 10:02:40 +01:00
|
|
|
import { executeLogic } from './executeLogic'
|
|
|
|
|
import { getNextGroup } from './getNextGroup'
|
|
|
|
|
import { executeIntegration } from './executeIntegration'
|
2023-03-15 12:21:52 +01:00
|
|
|
import { injectVariableValuesInButtonsInputBlock } from '@/features/blocks/inputs/buttons/injectVariableValuesInButtonsInputBlock'
|
|
|
|
|
import { deepParseVariables } from '@/features/variables/deepParseVariable'
|
|
|
|
|
import { computePaymentInputRuntimeOptions } from '@/features/blocks/inputs/payment/computePaymentInputRuntimeOptions'
|
2023-05-04 09:20:30 -04:00
|
|
|
import { injectVariableValuesInPictureChoiceBlock } from '@/features/blocks/inputs/pictureChoice/injectVariableValuesInPictureChoiceBlock'
|
2022-11-29 10:02:40 +01:00
|
|
|
|
|
|
|
|
export const executeGroup =
|
2023-03-02 14:37:09 +01:00
|
|
|
(
|
|
|
|
|
state: SessionState,
|
|
|
|
|
currentReply?: ChatReply,
|
|
|
|
|
currentLastBubbleId?: string
|
|
|
|
|
) =>
|
2022-11-29 10:02:40 +01:00
|
|
|
async (
|
|
|
|
|
group: Group
|
2023-01-16 12:13:21 +01:00
|
|
|
): Promise<ChatReply & { newSessionState: SessionState }> => {
|
2022-11-29 10:02:40 +01:00
|
|
|
const messages: ChatReply['messages'] = currentReply?.messages ?? []
|
2023-01-26 15:26:42 +01:00
|
|
|
let clientSideActions: ChatReply['clientSideActions'] =
|
|
|
|
|
currentReply?.clientSideActions
|
2023-01-25 11:27:47 +01:00
|
|
|
let logs: ChatReply['logs'] = currentReply?.logs
|
2022-11-29 10:02:40 +01:00
|
|
|
let nextEdgeId = null
|
2023-03-02 14:37:09 +01:00
|
|
|
let lastBubbleBlockId: string | undefined = currentLastBubbleId
|
2022-11-29 10:02:40 +01:00
|
|
|
|
|
|
|
|
let newSessionState = state
|
|
|
|
|
|
|
|
|
|
for (const block of group.blocks) {
|
|
|
|
|
nextEdgeId = block.outgoingEdgeId
|
|
|
|
|
|
|
|
|
|
if (isBubbleBlock(block)) {
|
2022-12-24 10:42:38 +01:00
|
|
|
messages.push(
|
2023-02-19 09:53:57 +01:00
|
|
|
parseBubbleBlock(newSessionState.typebot.variables)(block)
|
2022-12-24 10:42:38 +01:00
|
|
|
)
|
2023-01-27 10:54:59 +01:00
|
|
|
lastBubbleBlockId = block.id
|
2022-11-29 10:02:40 +01:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isInputBlock(block))
|
|
|
|
|
return {
|
|
|
|
|
messages,
|
2023-02-23 14:44:37 +01:00
|
|
|
input: await injectVariablesValueInBlock(newSessionState)(block),
|
2022-11-29 10:02:40 +01:00
|
|
|
newSessionState: {
|
|
|
|
|
...newSessionState,
|
|
|
|
|
currentBlock: {
|
|
|
|
|
groupId: group.id,
|
|
|
|
|
blockId: block.id,
|
|
|
|
|
},
|
|
|
|
|
},
|
2023-01-26 15:26:42 +01:00
|
|
|
clientSideActions,
|
2023-01-25 11:27:47 +01:00
|
|
|
logs,
|
2022-11-29 10:02:40 +01:00
|
|
|
}
|
|
|
|
|
const executionResponse = isLogicBlock(block)
|
2023-01-27 10:54:59 +01:00
|
|
|
? await executeLogic(newSessionState, lastBubbleBlockId)(block)
|
2022-11-29 10:02:40 +01:00
|
|
|
: isIntegrationBlock(block)
|
2023-01-27 10:54:59 +01:00
|
|
|
? await executeIntegration(newSessionState, lastBubbleBlockId)(block)
|
2022-11-29 10:02:40 +01:00
|
|
|
: null
|
|
|
|
|
|
|
|
|
|
if (!executionResponse) continue
|
2023-05-25 10:32:35 +02:00
|
|
|
if (executionResponse.logs)
|
|
|
|
|
logs = [...(logs ?? []), ...executionResponse.logs]
|
|
|
|
|
if (executionResponse.newSessionState)
|
|
|
|
|
newSessionState = executionResponse.newSessionState
|
2023-01-26 15:26:42 +01:00
|
|
|
if (
|
|
|
|
|
'clientSideActions' in executionResponse &&
|
|
|
|
|
executionResponse.clientSideActions
|
2023-04-14 12:11:42 +02:00
|
|
|
) {
|
2023-01-26 15:26:42 +01:00
|
|
|
clientSideActions = [
|
|
|
|
|
...(clientSideActions ?? []),
|
|
|
|
|
...executionResponse.clientSideActions,
|
|
|
|
|
]
|
2023-04-14 12:11:42 +02:00
|
|
|
if (
|
|
|
|
|
executionResponse.clientSideActions?.find(
|
2023-05-25 10:32:35 +02:00
|
|
|
(action) =>
|
|
|
|
|
'setVariable' in action || 'streamOpenAiChatCompletion' in action
|
2023-04-14 12:11:42 +02:00
|
|
|
)
|
|
|
|
|
) {
|
|
|
|
|
return {
|
|
|
|
|
messages,
|
|
|
|
|
newSessionState: {
|
|
|
|
|
...newSessionState,
|
|
|
|
|
currentBlock: {
|
|
|
|
|
groupId: group.id,
|
|
|
|
|
blockId: block.id,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
clientSideActions,
|
|
|
|
|
logs,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-16 12:13:21 +01:00
|
|
|
if (executionResponse.outgoingEdgeId) {
|
2022-11-29 10:02:40 +01:00
|
|
|
nextEdgeId = executionResponse.outgoingEdgeId
|
2023-01-16 12:13:21 +01:00
|
|
|
break
|
|
|
|
|
}
|
2022-11-29 10:02:40 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-25 11:27:47 +01:00
|
|
|
if (!nextEdgeId)
|
2023-01-26 15:26:42 +01:00
|
|
|
return { messages, newSessionState, clientSideActions, logs }
|
2022-11-29 10:02:40 +01:00
|
|
|
|
|
|
|
|
const nextGroup = getNextGroup(newSessionState)(nextEdgeId)
|
|
|
|
|
|
|
|
|
|
if (nextGroup?.updatedContext) newSessionState = nextGroup.updatedContext
|
|
|
|
|
|
|
|
|
|
if (!nextGroup) {
|
2023-01-26 15:26:42 +01:00
|
|
|
return { messages, newSessionState, clientSideActions, logs }
|
2022-11-29 10:02:40 +01:00
|
|
|
}
|
|
|
|
|
|
2023-03-02 14:37:09 +01:00
|
|
|
return executeGroup(
|
|
|
|
|
newSessionState,
|
|
|
|
|
{
|
|
|
|
|
messages,
|
|
|
|
|
clientSideActions,
|
|
|
|
|
logs,
|
|
|
|
|
},
|
|
|
|
|
lastBubbleBlockId
|
|
|
|
|
)(nextGroup.group)
|
2022-11-29 10:02:40 +01:00
|
|
|
}
|
|
|
|
|
|
2022-12-22 17:02:34 +01:00
|
|
|
const computeRuntimeOptions =
|
2023-03-07 14:41:57 +01:00
|
|
|
(state: Pick<SessionState, 'result' | 'typebot'>) =>
|
2022-12-22 17:02:34 +01:00
|
|
|
(block: InputBlock): Promise<RuntimeOptions> | undefined => {
|
|
|
|
|
switch (block.type) {
|
|
|
|
|
case InputBlockType.PAYMENT: {
|
|
|
|
|
return computePaymentInputRuntimeOptions(state)(block.options)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getPrefilledInputValue =
|
|
|
|
|
(variables: SessionState['typebot']['variables']) => (block: InputBlock) => {
|
2023-03-13 16:28:08 +01:00
|
|
|
const variableValue = variables.find(
|
|
|
|
|
(variable) =>
|
|
|
|
|
variable.id === block.options.variableId && isDefined(variable.value)
|
|
|
|
|
)?.value
|
|
|
|
|
if (!variableValue || Array.isArray(variableValue)) return
|
|
|
|
|
return variableValue
|
2022-12-22 17:02:34 +01:00
|
|
|
}
|
2023-02-19 09:53:57 +01:00
|
|
|
|
|
|
|
|
const parseBubbleBlock =
|
|
|
|
|
(variables: SessionState['typebot']['variables']) =>
|
|
|
|
|
(block: BubbleBlock): ChatReply['messages'][0] => {
|
|
|
|
|
switch (block.type) {
|
2023-03-15 17:47:05 +01:00
|
|
|
case BubbleBlockType.TEXT:
|
|
|
|
|
return deepParseVariables(variables, { takeLatestIfList: true })(block)
|
2023-02-19 09:53:57 +01:00
|
|
|
case BubbleBlockType.EMBED: {
|
2023-03-15 12:21:52 +01:00
|
|
|
const message = deepParseVariables(variables)(block)
|
2023-02-19 09:53:57 +01:00
|
|
|
return {
|
|
|
|
|
...message,
|
|
|
|
|
content: {
|
|
|
|
|
...message.content,
|
|
|
|
|
height:
|
|
|
|
|
typeof message.content.height === 'string'
|
|
|
|
|
? parseFloat(message.content.height)
|
|
|
|
|
: message.content.height,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
default:
|
2023-03-15 12:21:52 +01:00
|
|
|
return deepParseVariables(variables)(block)
|
2023-02-19 09:53:57 +01:00
|
|
|
}
|
|
|
|
|
}
|
2023-02-23 14:44:37 +01:00
|
|
|
|
|
|
|
|
const injectVariablesValueInBlock =
|
2023-03-07 14:41:57 +01:00
|
|
|
(state: Pick<SessionState, 'result' | 'typebot'>) =>
|
2023-02-23 14:44:37 +01:00
|
|
|
async (block: InputBlock): Promise<ChatReply['input']> => {
|
|
|
|
|
switch (block.type) {
|
|
|
|
|
case InputBlockType.CHOICE: {
|
|
|
|
|
return injectVariableValuesInButtonsInputBlock(state.typebot.variables)(
|
|
|
|
|
block
|
|
|
|
|
)
|
|
|
|
|
}
|
2023-05-04 09:20:30 -04:00
|
|
|
case InputBlockType.PICTURE_CHOICE: {
|
|
|
|
|
return injectVariableValuesInPictureChoiceBlock(
|
|
|
|
|
state.typebot.variables
|
|
|
|
|
)(block)
|
|
|
|
|
}
|
2023-02-23 14:44:37 +01:00
|
|
|
default: {
|
2023-03-15 12:21:52 +01:00
|
|
|
return deepParseVariables(state.typebot.variables)({
|
2023-02-23 14:44:37 +01:00
|
|
|
...block,
|
|
|
|
|
runtimeOptions: await computeRuntimeOptions(state)(block),
|
|
|
|
|
prefilledValue: getPrefilledInputValue(state.typebot.variables)(
|
|
|
|
|
block
|
|
|
|
|
),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|