2
0

(wait) Add pause option on Wait block

Closes #751
This commit is contained in:
Baptiste Arnaud
2023-09-04 14:52:16 +02:00
parent 66dc570527
commit 111fb323b1
16 changed files with 672 additions and 589 deletions

View File

@ -1,7 +1,15 @@
import { Stack } from '@chakra-ui/react'
import {
Accordion,
AccordionButton,
AccordionIcon,
AccordionItem,
AccordionPanel,
Stack,
} from '@chakra-ui/react'
import { WaitOptions } from '@typebot.io/schemas'
import React from 'react'
import { TextInput } from '@/components/inputs'
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
type Props = {
options: WaitOptions
@ -13,6 +21,10 @@ export const WaitSettings = ({ options, onOptionsChange }: Props) => {
onOptionsChange({ ...options, secondsToWaitFor })
}
const updateShouldPause = (shouldPause: boolean) => {
onOptionsChange({ ...options, shouldPause })
}
return (
<Stack spacing={4}>
<TextInput
@ -21,6 +33,22 @@ export const WaitSettings = ({ options, onOptionsChange }: Props) => {
onChange={handleSecondsChange}
placeholder="0"
/>
<Accordion allowToggle>
<AccordionItem>
<AccordionButton justifyContent="space-between">
Advanced
<AccordionIcon />
</AccordionButton>
<AccordionPanel py="4">
<SwitchWithLabel
label="Pause the flow"
moreInfoContent="When enabled, the flow is paused until the client sends another message. This is automatic on the web bot."
initialValue={options.shouldPause ?? false}
onCheckChange={updateShouldPause}
/>
</AccordionPanel>
</AccordionItem>
</Accordion>
</Stack>
)
}

View File

@ -7,3 +7,9 @@ This can be useful if you want the bot to emphasize on what's been said or to wa
:::caution
This should be used wisely. If you want the bot to write slower or faster in a more general sense, you need to check the [Typing emulation settings](/editor/settings#typing-emulation)
:::
## Pause the flow
You can enable the "Pause the flow" option if you ever need to mark a pause in the flow.
Under the hood, typebot always compute all the blocks between each input blocks. But sometimes you may want to display some messages before a long-running action like a slow webhook request.

View File

@ -2088,6 +2088,9 @@
"properties": {
"secondsToWaitFor": {
"type": "string"
},
"shouldPause": {
"type": "boolean"
}
},
"additionalProperties": false
@ -6381,6 +6384,9 @@
"properties": {
"secondsToWaitFor": {
"type": "string"
},
"shouldPause": {
"type": "boolean"
}
},
"additionalProperties": false
@ -10309,6 +10315,9 @@
"properties": {
"secondsToWaitFor": {
"type": "string"
},
"shouldPause": {
"type": "boolean"
}
},
"additionalProperties": false
@ -14377,6 +14386,9 @@
"properties": {
"secondsToWaitFor": {
"type": "string"
},
"shouldPause": {
"type": "boolean"
}
},
"additionalProperties": false
@ -18325,6 +18337,9 @@
"properties": {
"secondsToWaitFor": {
"type": "string"
},
"shouldPause": {
"type": "boolean"
}
},
"additionalProperties": false
@ -22328,6 +22343,9 @@
"properties": {
"secondsToWaitFor": {
"type": "string"
},
"shouldPause": {
"type": "boolean"
}
},
"additionalProperties": false
@ -26394,6 +26412,9 @@
"properties": {
"secondsToWaitFor": {
"type": "string"
},
"shouldPause": {
"type": "boolean"
}
},
"additionalProperties": false

View File

@ -1671,6 +1671,9 @@
"properties": {
"secondsToWaitFor": {
"type": "string"
},
"shouldPause": {
"type": "boolean"
}
},
"additionalProperties": false
@ -5204,6 +5207,9 @@
"properties": {
"lastBubbleBlockId": {
"type": "string"
},
"expectsDedicatedReply": {
"type": "boolean"
}
}
},

View File

@ -95,6 +95,7 @@ export const createChatCompletionOpenAI = async (
assistantMessageVariableName
),
},
expectsDedicatedReply: true,
},
],
outgoingEdgeId,

View File

@ -64,6 +64,7 @@ export const executeWebhookBlock = async (
clientSideActions: [
{
webhookToExecute: parsedWebhook,
expectsDedicatedReply: true,
},
],
}

View File

@ -34,6 +34,7 @@ export const executeSetVariable = (
setVariable: {
scriptToExecute,
},
expectsDedicatedReply: true,
},
],
}

View File

@ -19,6 +19,7 @@ export const executeWait = (
? [
{
wait: { secondsToWaitFor: parsedSecondsToWaitFor },
expectsDedicatedReply: block.options.shouldPause,
},
]
: undefined,

View File

@ -1,6 +1,6 @@
import { TRPCError } from '@trpc/server'
import {
AnswerInSessionState,
Block,
BubbleBlockType,
ChatReply,
InputBlock,
@ -8,8 +8,6 @@ import {
IntegrationBlockType,
LogicBlockType,
SessionState,
SetVariableBlock,
WebhookBlock,
defaultPaymentInputOptions,
invalidEmailDefaultRetryMessage,
} from '@typebot.io/schemas'
@ -21,7 +19,6 @@ import { formatPhoneNumber } from '@/features/blocks/inputs/phone/formatPhoneNum
import { validateUrl } from '@/features/blocks/inputs/url/validateUrl'
import { updateVariables } from '@/features/variables/updateVariables'
import { parseVariables } from '@/features/variables/parseVariables'
import { OpenAIBlock } from '@typebot.io/schemas/features/blocks/integrations/openai'
import { resumeChatCompletion } from '@/features/blocks/integrations/openai/resumeChatCompletion'
import { resumeWebhookExecution } from '@/features/blocks/integrations/webhook/resumeWebhookExecution'
import { upsertAnswer } from '../queries/upsertAnswer'
@ -80,11 +77,7 @@ export const continueBotFlow =
})(reply)
newSessionState = result.newSessionState
}
} else if (!isInputBlock(block))
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'Current block is not an input block',
})
}
let formattedReply: string | undefined
@ -276,10 +269,7 @@ const setNewAnswerInState =
const getOutgoingEdgeId =
(state: Pick<SessionState, 'typebotsQueue'>) =>
(
block: InputBlock | SetVariableBlock | OpenAIBlock | WebhookBlock,
reply: string | undefined
) => {
(block: Block, reply: string | undefined) => {
const variables = state.typebotsQueue[0].typebot.variables
if (
block.type === InputBlockType.CHOICE &&

View File

@ -94,10 +94,7 @@ export const executeGroup =
]
if (
executionResponse.clientSideActions?.find(
(action) =>
'setVariable' in action ||
'streamOpenAiChatCompletion' in action ||
'webhookToExecute' in action
(action) => action.expectsDedicatedReply
)
) {
return {

View File

@ -22,10 +22,7 @@ export const saveStateToDatabase = async ({
clientSideActions,
}: Props) => {
const containsSetVariableClientSideAction = clientSideActions?.some(
(action) =>
'setVariable' in action ||
'webhookToExecute' in action ||
'streamOpenAiChatCompletion' in action
(action) => action.expectsDedicatedReply
)
const isCompleted = Boolean(!input && !containsSetVariableClientSideAction)

View File

@ -165,10 +165,7 @@ export const startSession = async ({
}
const clientSideActionsNeedSessionId = clientSideActions?.some(
(action) =>
'setVariable' in action ||
'streamOpenAiChatCompletion' in action ||
'webhookToExecute' in action
(action) => action.expectsDedicatedReply
)
if (!input && !clientSideActionsNeedSessionId)