diff --git a/apps/builder/components/editor/StepsSideBar/LearnAutomatedTasks.tsx b/apps/builder/components/editor/StepsSideBar/LearnAutomatedTasks.tsx
index 7c63310ac6..d98064098c 100644
--- a/apps/builder/components/editor/StepsSideBar/LearnAutomatedTasks.tsx
+++ b/apps/builder/components/editor/StepsSideBar/LearnAutomatedTasks.tsx
@@ -107,6 +107,7 @@ const LearnAutomatedTasks = () => {
justifyContent="flex-start"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
+ gap={0}
>
{
const { draggedStepType } = useStepDnd()
const [isMouseDown, setIsMouseDown] = useState(false)
+ const { typebot } = useTypebot()
useEffect(() => {
setIsMouseDown(draggedStepType === type)
@@ -35,10 +37,10 @@ export const StepCard = ({
const handleMouseDown = (e: React.MouseEvent) => onMouseDown(e, type)
- const shouldAddGradientBorder = [
- WOZStepType.MESSAGE,
- WOZStepType.INTERPRET_DATA_WITH_AI,
- ].includes(type as WOZStepType)
+ const shouldAddGradientBorder =
+ [WOZStepType.MESSAGE, WOZStepType.INTERPRET_DATA_WITH_AI].includes(
+ type as WOZStepType
+ ) && typebot?.availableFor?.includes('automated-tasks')
return (
{
)
}
- const EVENT_AVAILABLE_STEPS: StepType[] = [IntegrationStepType.WEBHOOK]
+ const EVENT_AVAILABLE_STEPS: StepType[] = [
+ IntegrationStepType.WEBHOOK,
+ WOZStepType.INTERPRET_DATA_WITH_AI,
+ ]
const AUTOMATED_TASKS_AVAILABLE_STEPS: StepType[] = [
WOZStepType.MESSAGE,
WOZStepType.INTERPRET_DATA_WITH_AI,
diff --git a/apps/builder/components/octaComponents/OctaSelect/OctaSelect.type.ts b/apps/builder/components/octaComponents/OctaSelect/OctaSelect.type.ts
index 1bade7cf9c..004547fca2 100644
--- a/apps/builder/components/octaComponents/OctaSelect/OctaSelect.type.ts
+++ b/apps/builder/components/octaComponents/OctaSelect/OctaSelect.type.ts
@@ -1,35 +1,35 @@
import React, { DetailedHTMLProps, InputHTMLAttributes } from 'react'
-import { SELECT_ACTION, SELECT_ACTIONS } from './OctaSelect';
+import { SELECT_ACTION } from './OctaSelect'
-export type OctaSelectProps = {
- onChange: (value: any, itemFull?: any) => void
+export type OctaSelectProps = {
+ onChange: (value: T, itemFull?: T) => void
defaultSelected?: any
- label?: string;
- findable?: boolean;
- options?: Array;
- showEdit?: boolean;
- showDelete?: boolean;
+ label?: string
+ findable?: boolean
+ options?: Array
+ showEdit?: boolean
+ showDelete?: boolean
onIconClicked?: (value: any, action: SELECT_ACTION) => {}
} & DetailedHTMLProps, HTMLSelectElement>
export type OptionProps = {
- value: any;
- children?: string;
- optionKey?: string | number;
- isTitle?: boolean;
- disabled?: boolean;
- selected: any;
- showEdit?: boolean;
- showDelete?: boolean;
+ value: any
+ children?: string
+ optionKey?: string | number
+ isTitle?: boolean
+ disabled?: boolean
+ selected: any
+ showEdit?: boolean
+ showDelete?: boolean
onIconClicked?: (value: any, action: SELECT_ACTION) => {}
} & DetailedHTMLProps, HTMLLIElement>
export type OptionType = {
- value: any;
- label: string;
- isTitle?: boolean;
- disabled?: boolean;
- key: string | number;
- optionKey?: string | number;
- subType?: string;
+ value: any
+ label: string
+ isTitle?: boolean
+ disabled?: boolean
+ key: string | number
+ optionKey?: string | number
+ subType?: string
}
diff --git a/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/InterpretDataWithAI/InterpretDataWithAI.tsx b/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/InterpretDataWithAI/InterpretDataWithAI.tsx
index 7191561ef7..f01bb9cda2 100644
--- a/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/InterpretDataWithAI/InterpretDataWithAI.tsx
+++ b/apps/builder/components/shared/Graph/Nodes/StepNode/SettingsPopoverContent/bodies/InterpretDataWithAI/InterpretDataWithAI.tsx
@@ -12,13 +12,19 @@ import {
Spinner,
HStack,
} from '@chakra-ui/react'
-import { IntegrationStepType, WOZInterpretDataWithAIOptions } from 'models'
-import { useMemo, useState, useRef, useEffect } from 'react'
+import {
+ IntegrationStepType,
+ WOZInterpretDataWithAIOptions,
+ WOZInterpretDataWithAIResponseFormat,
+} from 'models'
+import { useMemo, useState, useRef } from 'react'
import { useInterpretDataWithAI } from 'hooks/InterpretDataWithAI/useInterpretDataWithAI'
import { VariablesMenu } from './VariablesMenu'
import { MdInfoOutline } from 'react-icons/md'
import { WOZInterpretDataWithAI } from 'models'
import { getDeepKeys } from 'services/integrations'
+import { useTypebot } from 'contexts/TypebotContext'
+import OctaSelect from 'components/octaComponents/OctaSelect/OctaSelect'
type Props = {
step: WOZInterpretDataWithAI
@@ -34,6 +40,9 @@ export const InterpretDataWithAI = ({ step, onContentChange }: Props) => {
testReturn,
refetch,
} = useInterpretDataWithAI({ step })
+
+ const { typebot } = useTypebot()
+ const isAutomatedTasksBot = typebot?.availableFor.includes('automated-tasks')
const [isTesting, setIsTesting] = useState(false)
const [resultOfInterpretWithAi, setResultOfInterpretWithAi] =
@@ -78,6 +87,13 @@ export const InterpretDataWithAI = ({ step, onContentChange }: Props) => {
}, 0)
}
+ const stepDescription = useMemo(() => {
+ if (isAutomatedTasksBot) {
+ return 'Defina como a IA deve apresentar os dados coletados na conversa.'
+ }
+ return 'Defina como a IA deve apresentar os dados coletados para o próximo passo do fluxo.'
+ }, [])
+
const placeholderInstructions = useMemo(() => {
return `Ex: Retorne ao cliente a lista dos tickets encontrados.
\b\b
@@ -85,6 +101,16 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
{{ criado-em }}`
}, [])
+ const placeholderInstructionsEvents = useMemo(() => {
+ if (
+ step?.content?.responseFormat ===
+ WOZInterpretDataWithAIResponseFormat.JSON
+ ) {
+ return `Ex: Crie um JSON com os dados do ticket. Use as variáveis: {ticked_id}, {assunto}, {responsavel}, {data_de_criacao}`
+ }
+ return `Ex: Gere um resumo das informações coletadas, listando o motivo do contato, o status atual e a data de abertura.`
+ }, [step?.content?.responseFormat])
+
const tooltipInstructions = useMemo(() => {
return `Como instruir a IA?
@@ -94,6 +120,27 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
`
}, [])
+ const tooltipInstructionsEvents = useMemo(() => {
+ return `Como instruir a IA?
+
+- Defina a estrutura de dados (ex: um JSON) que o próximo passo do fluxo deve receber.
+- Escreva manualmente o nome das variáveis capturadas nos passos anteriores usando chaves, como {nome_da_variavel}.
+- Este campo é técnico: a IA usará suas instruções para organizar as informações antes de enviá-las ao sistema, sem que o cliente veja este texto.
+
`
+ }, [])
+
+ const tooltipInstructionsResponseFormat = useMemo(() => {
+ return `Mensagem natural (texto):
+
+ Quando a informação for usada como um texto simples ou resumo em etapas posteriores do fluxo.
+
+
+ JSON (estrutura):
+
+ Quando o próximo passo é uma integração/sistema externo e é preciso transformar informação em código para enviar para outro sistema.
+ `
+ }, [])
+
const responseKeys = useMemo(
() => getDeepKeys(data?.response || {}),
[data?.response]
@@ -122,6 +169,30 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
}
}
+ const handleSelectResponseFormat = (
+ value: WOZInterpretDataWithAIResponseFormat
+ ) => {
+ onContentChange({
+ ...step.content,
+ responseFormat: value,
+ })
+ }
+
+ const responseFormatOptions = useMemo(() => {
+ return [
+ {
+ key: 'json',
+ label: 'JSON',
+ value: WOZInterpretDataWithAIResponseFormat.JSON,
+ },
+ {
+ key: 'text',
+ label: 'Mensagem natural',
+ value: WOZInterpretDataWithAIResponseFormat.TEXT,
+ },
+ ]
+ }, [])
+
const componentToRender = useMemo(() => {
if (whoIsConnectedOnMyBlock?.length <= 0) {
return (
@@ -133,7 +204,10 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
if (whoIsConnectedOnMyBlock?.length === 1) {
const block = whoIsConnectedOnMyBlock[0]
- if (block.steps[0].type !== IntegrationStepType.WEBHOOK)
+ if (
+ block.steps[0].type !== IntegrationStepType.WEBHOOK &&
+ isAutomatedTasksBot
+ )
return (
@@ -148,8 +222,11 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
return (
- Este bloco deve receber apenas uma conexão, sendo esta conexão um
- componente chamado "Conecte a outro sistema"
+ Este bloco deve receber apenas uma conexão{' '}
+ {isAutomatedTasksBot
+ ? `, sendo esta conexão um
+ componente chamado "Conecte a outro sistema"`
+ : ''}
)
@@ -164,7 +241,7 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
)
}
- if (!success) {
+ if (!success && isAutomatedTasksBot) {
return (
@@ -179,18 +256,52 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
}
return (
-
-
- Defina como a IA deve apresentar os dados coletados na conversa.
-
-
+
+ {stepDescription}
+ {!isAutomatedTasksBot && (
+
+
+ Formato de saída
+
+ }
+ hasArrow
+ >
+
+
+
+
+
+
+ )}
+ {!isAutomatedTasksBot && (
+
+ )}
Instruções de retorno
}
hasArrow
@@ -208,7 +319,11 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
-
-
-
+ {responseKeys.length > 0 && (
+
+
+
+ )}
A IA usará este texto como base. Não é necessário dar comandos de
@@ -250,19 +367,21 @@ Use as variáveis: {{ numero-ticket }}, {{ status-ticket }},
)}
-
+ {isAutomatedTasksBot && (
+
+ )}
)
diff --git a/apps/builder/components/shared/Graph/Nodes/StepNode/StepNodeContent/contents/WOZInterpretDataWithAI/WOZInterpretDataWithAIContent.tsx b/apps/builder/components/shared/Graph/Nodes/StepNode/StepNodeContent/contents/WOZInterpretDataWithAI/WOZInterpretDataWithAIContent.tsx
index 099763e3b5..b900854051 100644
--- a/apps/builder/components/shared/Graph/Nodes/StepNode/StepNodeContent/contents/WOZInterpretDataWithAI/WOZInterpretDataWithAIContent.tsx
+++ b/apps/builder/components/shared/Graph/Nodes/StepNode/StepNodeContent/contents/WOZInterpretDataWithAI/WOZInterpretDataWithAIContent.tsx
@@ -1,4 +1,7 @@
-import { WOZInterpretDataWithAI } from 'models'
+import {
+ WOZInterpretDataWithAI,
+ WOZInterpretDataWithAIResponseFormat,
+} from 'models'
import React from 'react'
import { Stack, Text, Tag } from '@chakra-ui/react'
import { OctaDivider } from 'components/octaComponents/OctaDivider/OctaDivider'
@@ -16,7 +19,10 @@ const WOZInterpretDataWithAIContent = ({ step }: Props) => {
Enviar resposta como{' '}
- JSON
+ {step.content.responseFormat ===
+ WOZInterpretDataWithAIResponseFormat.JSON
+ ? 'JSON'
+ : 'Mensagem natural'}
diff --git a/apps/builder/hooks/InterpretDataWithAI/useInterpretDataWithAI.ts b/apps/builder/hooks/InterpretDataWithAI/useInterpretDataWithAI.ts
index cf2b5124f4..23076e90ad 100644
--- a/apps/builder/hooks/InterpretDataWithAI/useInterpretDataWithAI.ts
+++ b/apps/builder/hooks/InterpretDataWithAI/useInterpretDataWithAI.ts
@@ -73,7 +73,12 @@ export const useInterpretDataWithAI = ({
}
const requestParams = useMemo(() => {
- if (!whoIsConnectedOnMyBlock?.length || !typebot) return null
+ if (
+ !whoIsConnectedOnMyBlock?.length ||
+ !typebot ||
+ typebot?.availableFor?.includes('event')
+ )
+ return null
const block = whoIsConnectedOnMyBlock[0]
diff --git a/packages/models/src/typebot/steps/octaStep.ts b/packages/models/src/typebot/steps/octaStep.ts
index 6946941e63..86adf18d7a 100644
--- a/packages/models/src/typebot/steps/octaStep.ts
+++ b/packages/models/src/typebot/steps/octaStep.ts
@@ -281,8 +281,14 @@ export type WOZAssignOptions = BaseOctaOptions & {
}>
}
+export enum WOZInterpretDataWithAIResponseFormat {
+ TEXT = 'text',
+ JSON = 'json',
+}
+
export type WOZInterpretDataWithAIOptions = {
systemMessage: string
+ responseFormat?: WOZInterpretDataWithAIResponseFormat
}
export type CallOtherBotOptions = BaseOctaOptions & {
@@ -460,6 +466,7 @@ export const defaultWOZAssignOptions: WOZAssignOptions = {
export const defaultWOZInterpretDataWithAIOptions: WOZInterpretDataWithAIOptions =
{
systemMessage: '',
+ responseFormat: WOZInterpretDataWithAIResponseFormat.TEXT,
}
export const defaultCallOtherBotOptions: CallOtherBotOptions = {
@@ -471,20 +478,20 @@ export const defaultCallOtherBotOptions: CallOtherBotOptions = {
const seeYa = 'Até mais!'
export const defaultEndConversationBubbleContent: EndConversationBubbleContent =
-{
- html: `
${seeYa}
`,
- richText: [
- {
- children: [
- {
- text: seeYa,
- },
- ],
- type: 'p',
- },
- ],
- plainText: seeYa,
-}
+ {
+ html: `${seeYa}
`,
+ richText: [
+ {
+ children: [
+ {
+ text: seeYa,
+ },
+ ],
+ type: 'p',
+ },
+ ],
+ plainText: seeYa,
+ }
export const defaultCommerceOptions: CommerceOptions = {
catalogId: '',