Skip to content

Commit

Permalink
✨ Add Zemantic AI Integration block (#752)
Browse files Browse the repository at this point in the history
Co-authored-by: Baptiste Arnaud <contact@baptiste-arnaud.fr>
  • Loading branch information
ezynda3 and baptisteArno authored Sep 8, 2023
1 parent fbb198a commit 75e4b16
Show file tree
Hide file tree
Showing 36 changed files with 1,668 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ typebotsToFix.json
snapshots

.env
.typebot-build
.typebot-build
3 changes: 2 additions & 1 deletion apps/builder/src/components/inputs/NumberInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ export const NumberInput = <HasVariable extends boolean>({
isRequired={isRequired}
justifyContent="space-between"
width={label ? 'full' : 'auto'}
spacing={0}
>
{label && (
<FormLabel mb="0" flexShrink={0}>
<FormLabel mb="2" flexShrink={0}>
{label}{' '}
{moreInfoTooltip && (
<MoreInfoTooltip>{moreInfoTooltip}</MoreInfoTooltip>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Select } from '@/components/inputs/Select'
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
import { useToast } from '@/hooks/useToast'
import { trpc } from '@/lib/trpc'

type Props = {
credentialsId: string
blockId: string
defaultValue: string
onChange: (projectId: string | undefined) => void
}

export const ProjectsDropdown = ({
defaultValue,
onChange,
credentialsId,
}: Props) => {
const { typebot } = useTypebot()
const { workspace } = useWorkspace()
const { showToast } = useToast()

const { data } = trpc.zemanticAi.listProjects.useQuery(
{
credentialsId,
workspaceId: workspace?.id as string,
},
{
enabled: !!typebot && !!workspace,
onError: (error) => {
showToast({
description: error.message,
status: 'error',
})
},
}
)

return (
<Select
items={data?.projects as { label: string; value: string }[]}
selectedItem={defaultValue}
onSelect={onChange}
placeholder="Select a project"
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { DropdownList } from '@/components/DropdownList'
import { VariableSearchInput } from '@/components/inputs/VariableSearchInput'
import { TableListItemProps } from '@/components/TableList'
import { Stack } from '@chakra-ui/react'
import { Variable } from '@typebot.io/schemas'
import {
ZemanticAiOptions,
searchResponseValues,
} from '@typebot.io/schemas/features/blocks/integrations/zemanticAi'

type Props = TableListItemProps<ZemanticAiOptions['responseMapping'][number]>

export const SearchResponseItem = ({ item, onItemChange }: Props) => {
const changeValueToExtract = (
valueToExtract: (typeof searchResponseValues)[number]
) => {
onItemChange({ ...item, valueToExtract })
}

const changeVariableId = (variable: Pick<Variable, 'id'> | undefined) => {
onItemChange({ ...item, variableId: variable ? variable.id : undefined })
}

return (
<Stack p="4" rounded="md" flex="1" borderWidth="1px">
<DropdownList
currentItem={item.valueToExtract ?? 'Summary'}
items={searchResponseValues}
onItemSelect={changeValueToExtract}
/>
<VariableSearchInput
onSelectVariable={changeVariableId}
initialVariableId={item.variableId}
/>
</Stack>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { TextInput } from '@/components/inputs/TextInput'
import { TextLink } from '@/components/TextLink'
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
import { useToast } from '@/hooks/useToast'
import { trpc } from '@/lib/trpc'
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
Stack,
ModalFooter,
Button,
} from '@chakra-ui/react'
import React, { useState } from 'react'

const zemanticAIDashboardPage = 'https://zemantic.ai/dashboard/settings'

type Props = {
isOpen: boolean
onClose: () => void
onNewCredentials: (id: string) => void
}

export const ZemanticAiCredentialsModal = ({
isOpen,
onClose,
onNewCredentials,
}: Props) => {
const { workspace } = useWorkspace()
const { showToast } = useToast()
const [apiKey, setApiKey] = useState('')
const [name, setName] = useState('')

const [isCreating, setIsCreating] = useState(false)

const {
credentials: {
listCredentials: { refetch: refetchCredentials },
},
} = trpc.useContext()
const { mutate } = trpc.credentials.createCredentials.useMutation({
onMutate: () => setIsCreating(true),
onSettled: () => setIsCreating(false),
onError: (err) => {
showToast({
description: err.message,
status: 'error',
})
},
onSuccess: (data) => {
refetchCredentials()
onNewCredentials(data.credentialsId)
onClose()
},
})

const createZemanticAiCredentials = async (e: React.FormEvent) => {
e.preventDefault()
if (!workspace) return
mutate({
credentials: {
type: 'zemanticAi',
workspaceId: workspace.id,
name,
data: {
apiKey,
},
},
})
}

return (
<Modal isOpen={isOpen} onClose={onClose} size="lg">
<ModalOverlay />
<ModalContent>
<ModalHeader>Add Zemantic AI account</ModalHeader>
<ModalCloseButton />
<form onSubmit={createZemanticAiCredentials}>
<ModalBody as={Stack} spacing="6">
<TextInput
isRequired
label="Name"
onChange={setName}
placeholder="My account"
withVariableButton={false}
debounceTimeout={0}
/>
<TextInput
isRequired
type="password"
label="API key"
helperText={
<>
You can generate an API key{' '}
<TextLink href={zemanticAIDashboardPage} isExternal>
here
</TextLink>
.
</>
}
onChange={setApiKey}
placeholder="ze..."
withVariableButton={false}
debounceTimeout={0}
/>
</ModalBody>

<ModalFooter>
<Button
type="submit"
isLoading={isCreating}
isDisabled={apiKey === '' || name === ''}
colorScheme="blue"
>
Create
</Button>
</ModalFooter>
</form>
</ModalContent>
</Modal>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Icon, IconProps } from '@chakra-ui/react'

export const ZemanticAiLogo = (props: IconProps) => (
<Icon viewBox="0 0 24 24" {...props}>
<g transform="matrix(.049281 0 0 .064343 -.27105 -3.4424)">
<path
d="m99.5 205.5v221h-94v-373h94v152z"
fill="#8771b1"
opacity=".991"
/>
<path
d="m284.5 426.5v-221-152h94v373h-94z"
fill="#f05b4e"
opacity=".99"
/>
<path d="m99.5 205.5h93v221h-93v-221z" fill="#ec9896" />
<path d="m192.5 205.5h92v221h-92v-221z" fill="#efe894" />
<path d="m398.5 298.5h94v128h-94v-128z" fill="#46bb91" opacity=".989" />
</g>
</Icon>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import { Stack, Text } from '@chakra-ui/react'
import { ZemanticAiOptions } from '@typebot.io/schemas'
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
import { SetVariableLabel } from '@/components/SetVariableLabel'

type Props = {
options: ZemanticAiOptions
}

export const ZemanticAiNodeBody = ({
options: { query, projectId, responseMapping },
}: Props) => {
const { typebot } = useTypebot()
return (
<Stack>
<Text
color={query && projectId ? 'currentcolor' : 'gray.500'}
noOfLines={1}
>
{query && projectId ? `Ask: ${query}` : 'Configure...'}
</Text>
{typebot &&
responseMapping
.map((mapping) => mapping.variableId)
.map((variableId, idx) =>
variableId ? (
<SetVariableLabel
key={variableId + idx}
variables={typebot.variables}
variableId={variableId}
/>
) : null
)}
</Stack>
)
}
Loading

4 comments on commit 75e4b16

@vercel
Copy link

@vercel vercel bot commented on 75e4b16 Sep 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 75e4b16 Sep 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./apps/docs

docs-typebot-io.vercel.app
docs.typebot.io
docs-git-main-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 75e4b16 Sep 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

app.typebot.io
builder-v2-typebot-io.vercel.app
builder-v2-git-main-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 75e4b16 Sep 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2 – ./apps/viewer

bot.tobb.pro
cinecorn.com
ezbooking.ai
gniorder.com
help.taxt.co
kusamint.com
psmix.online
receita.info
rhino.cr8.ai
sheep.cr8.ai
snake.cr8.ai
svhm.mprs.in
tiger.cr8.ai
video.cr8.ai
webwhats.fun
webwhats.pro
yoda.riku.ai
zebra.cr8.ai
alvodelas.com
bemestar.club
bot.krdfy.com
cat.hidden.sg
cgcassets.com
cnvhub.com.br
drapamela.com
facelabko.com
filmylogy.com
goldorayo.com
rabbit.cr8.ai
shop.mexwa.my
signup.cr8.ai
start.taxt.co
theusm.com.br
turkey.cr8.ai
vhpage.cr8.ai
vitamyway.com
whatchat.site
www.wiccom.it
am.nigerias.io
an.nigerias.io
app.yvon.earth
ar.nigerias.io
bot.enreso.org
bot.mail2wa.me
bot.rslabs.pro
bots.bng.tools
bots.bridge.ai
cares.urlabout.me
chat.ezbooking.ai
chat.gaswadern.de
chat.gniorder.com
chat.onrentme.com
chat.rojie.online
chatdocidadao.com
chatwebonline.com
fmm.wpwakanda.com
footballmeetup.ie
gentleman-shop.fr
island.wakanda.is
k1.kandabrand.com
kp.pedroknoll.com
lb.ticketfute.com
metodoelev.com.br
nutriandreia.shop
ov1.wpwakanda.com
ov2.wpwakanda.com
ov3.wpwakanda.com
pcb.drapamela.com
softwarelucra.com
support.triplo.ai
survey.collab.day
test.eqfeqfeq.com
viewer.typebot.io
welcome.triplo.ai
www.thegymgame.it
zeropendencia.com
1988.bouclidom.com
a.onewebcenter.com
amancarseat.online
amostra-safe.click
andreimayer.com.br
bebesemcolicas.com
bot.innovacion.fun
bot.jogodospix.com
bot.jogomilion.com
bot.lucide.contact
bot.neferlopez.com
bot.photonative.de
bot.samplehunt.com
bot.sinalcerto.com
bot.wphelpchat.com
bots.robomotion.io
cadu.uninta.edu.br
chat.hand-made.one
bot.buenanoticia.fun
bot.conhecaojogo.com
bot.cotemeuplano.com
bot.gameincrivel.com
bot.gamesimples.club
bot.jogoquelucra.com

Please sign in to comment.