✨ Add Zemantic AI Integration block (#752)
Co-authored-by: Baptiste Arnaud <contact@baptiste-arnaud.fr>
This commit is contained in:
@@ -99,9 +99,10 @@ export const NumberInput = <HasVariable extends boolean>({
|
|||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
width={label ? 'full' : 'auto'}
|
width={label ? 'full' : 'auto'}
|
||||||
|
spacing={0}
|
||||||
>
|
>
|
||||||
{label && (
|
{label && (
|
||||||
<FormLabel mb="0" flexShrink={0}>
|
<FormLabel mb="2" flexShrink={0}>
|
||||||
{label}{' '}
|
{label}{' '}
|
||||||
{moreInfoTooltip && (
|
{moreInfoTooltip && (
|
||||||
<MoreInfoTooltip>{moreInfoTooltip}</MoreInfoTooltip>
|
<MoreInfoTooltip>{moreInfoTooltip}</MoreInfoTooltip>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
)
|
||||||
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
import { TextInput, Textarea, NumberInput } from '@/components/inputs'
|
||||||
|
import { CredentialsDropdown } from '@/features/credentials/components/CredentialsDropdown'
|
||||||
|
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionButton,
|
||||||
|
AccordionIcon,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionPanel,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
useDisclosure,
|
||||||
|
} from '@chakra-ui/react'
|
||||||
|
import { isEmpty } from '@typebot.io/lib'
|
||||||
|
import { ZemanticAiBlock } from '@typebot.io/schemas'
|
||||||
|
import { ZemanticAiCredentialsModal } from './ZemanticAiCredentialsModal'
|
||||||
|
import { ProjectsDropdown } from './ProjectsDropdown'
|
||||||
|
import { SearchResponseItem } from './SearchResponseItem'
|
||||||
|
import { TableList } from '@/components/TableList'
|
||||||
|
import { createId } from '@paralleldrive/cuid2'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
block: ZemanticAiBlock
|
||||||
|
onOptionsChange: (options: ZemanticAiBlock['options']) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ZemanticAiSettings = ({
|
||||||
|
block: { id: blockId, options },
|
||||||
|
onOptionsChange,
|
||||||
|
}: Props) => {
|
||||||
|
const { workspace } = useWorkspace()
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||||
|
|
||||||
|
const updateCredentialsId = (credentialsId: string | undefined) => {
|
||||||
|
onOptionsChange({
|
||||||
|
...options,
|
||||||
|
credentialsId,
|
||||||
|
responseMapping: [
|
||||||
|
{
|
||||||
|
id: createId(),
|
||||||
|
valueToExtract: 'Summary',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateProjectId = (projectId: string | undefined) => {
|
||||||
|
onOptionsChange({
|
||||||
|
...options,
|
||||||
|
projectId: isEmpty(projectId) ? undefined : projectId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateQuery = (query: string) => {
|
||||||
|
onOptionsChange({
|
||||||
|
...options,
|
||||||
|
query: isEmpty(query) ? undefined : query,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateMaxResults = (
|
||||||
|
maxResults: number | `{{${string}}}` | undefined
|
||||||
|
) => {
|
||||||
|
onOptionsChange({
|
||||||
|
...options,
|
||||||
|
maxResults: maxResults as number,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateSystemPrompt = (systemPrompt: string) => {
|
||||||
|
onOptionsChange({
|
||||||
|
...options,
|
||||||
|
systemPrompt: isEmpty(systemPrompt) ? undefined : systemPrompt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatePrompt = (prompt: string) => {
|
||||||
|
onOptionsChange({
|
||||||
|
...options,
|
||||||
|
prompt: isEmpty(prompt) ? undefined : prompt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateResponseMapping = (
|
||||||
|
responseMapping: typeof options.responseMapping
|
||||||
|
) => {
|
||||||
|
onOptionsChange({
|
||||||
|
...options,
|
||||||
|
responseMapping,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack spacing={4}>
|
||||||
|
{workspace && (
|
||||||
|
<>
|
||||||
|
<CredentialsDropdown
|
||||||
|
type="zemanticAi"
|
||||||
|
workspaceId={workspace.id}
|
||||||
|
currentCredentialsId={options?.credentialsId}
|
||||||
|
onCredentialsSelect={updateCredentialsId}
|
||||||
|
onCreateNewClick={onOpen}
|
||||||
|
credentialsName="Zemantic AI account"
|
||||||
|
/>
|
||||||
|
<ZemanticAiCredentialsModal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
onNewCredentials={updateCredentialsId}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{options?.credentialsId && (
|
||||||
|
<>
|
||||||
|
<ProjectsDropdown
|
||||||
|
credentialsId={options?.credentialsId as string}
|
||||||
|
defaultValue={(options?.projectId as string) ?? ''}
|
||||||
|
onChange={updateProjectId}
|
||||||
|
blockId={blockId as string}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
label="Query:"
|
||||||
|
moreInfoTooltip="The question you want to ask or search against the documents in the project."
|
||||||
|
defaultValue={options?.query ?? ''}
|
||||||
|
onChange={updateQuery}
|
||||||
|
withVariableButton={true}
|
||||||
|
placeholder="Content"
|
||||||
|
/>
|
||||||
|
<NumberInput
|
||||||
|
label="Max Results:"
|
||||||
|
moreInfoTooltip="The maximum number of document chunk results to return from your search."
|
||||||
|
direction="column"
|
||||||
|
defaultValue={options?.maxResults}
|
||||||
|
onValueChange={updateMaxResults}
|
||||||
|
placeholder="i.e. 3"
|
||||||
|
w="full"
|
||||||
|
/>
|
||||||
|
<Accordion allowMultiple={true}>
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionButton>
|
||||||
|
<Text w="full" textAlign="left">
|
||||||
|
Advanced settings
|
||||||
|
</Text>
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel pb={4} as={Stack} spacing={6}>
|
||||||
|
<Textarea
|
||||||
|
label="System Prompt:"
|
||||||
|
moreInfoTooltip="System prompt to send to the summarization LLM. This is prepended to the prompt and helps guide system behavior."
|
||||||
|
defaultValue={options?.systemPrompt ?? ''}
|
||||||
|
onChange={updateSystemPrompt}
|
||||||
|
placeholder="System Prompt"
|
||||||
|
withVariableButton={true}
|
||||||
|
/>
|
||||||
|
<Textarea
|
||||||
|
label="Prompt:"
|
||||||
|
moreInfoTooltip="Prompt to send to the summarization LLM."
|
||||||
|
defaultValue={options?.prompt ?? ''}
|
||||||
|
onChange={updatePrompt}
|
||||||
|
placeholder="Prompt"
|
||||||
|
withVariableButton={true}
|
||||||
|
/>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem>
|
||||||
|
<AccordionButton>
|
||||||
|
<Text w="full" textAlign="left">
|
||||||
|
Save answer
|
||||||
|
</Text>
|
||||||
|
<AccordionIcon />
|
||||||
|
</AccordionButton>
|
||||||
|
<AccordionPanel pt="4">
|
||||||
|
<TableList
|
||||||
|
initialItems={options.responseMapping ?? []}
|
||||||
|
Item={SearchResponseItem}
|
||||||
|
onItemsChange={updateResponseMapping}
|
||||||
|
newItemDefaultProps={{ valueToExtract: 'Summary' }}
|
||||||
|
/>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import prisma from '@/lib/prisma'
|
||||||
|
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||||
|
import { TRPCError } from '@trpc/server'
|
||||||
|
import { z } from 'zod'
|
||||||
|
import { isReadWorkspaceFobidden } from '@/features/workspace/helpers/isReadWorkspaceFobidden'
|
||||||
|
import { decrypt } from '@typebot.io/lib/api'
|
||||||
|
import { ZemanticAiCredentials } from '@typebot.io/schemas/features/blocks/integrations/zemanticAi'
|
||||||
|
import got from 'got'
|
||||||
|
|
||||||
|
export const listProjects = authenticatedProcedure
|
||||||
|
.meta({
|
||||||
|
openapi: {
|
||||||
|
method: 'GET',
|
||||||
|
path: '/zemantic-ai/projects',
|
||||||
|
protect: true,
|
||||||
|
summary: 'List Zemantic AI projects',
|
||||||
|
tags: ['ZemanticAi'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
credentialsId: z.string(),
|
||||||
|
workspaceId: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.output(
|
||||||
|
z.object({
|
||||||
|
projects: z.array(
|
||||||
|
z.object({
|
||||||
|
label: z.string(),
|
||||||
|
value: z.string(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.query(async ({ input: { credentialsId, workspaceId }, ctx: { user } }) => {
|
||||||
|
const workspace = await prisma.workspace.findFirst({
|
||||||
|
where: { id: workspaceId },
|
||||||
|
select: {
|
||||||
|
members: {
|
||||||
|
select: {
|
||||||
|
userId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
credentials: {
|
||||||
|
where: {
|
||||||
|
id: credentialsId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
data: true,
|
||||||
|
iv: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!workspace || isReadWorkspaceFobidden(workspace, user))
|
||||||
|
throw new TRPCError({
|
||||||
|
code: 'NOT_FOUND',
|
||||||
|
message: 'No workspace found',
|
||||||
|
})
|
||||||
|
|
||||||
|
const credentials = workspace.credentials.at(0)
|
||||||
|
|
||||||
|
if (!credentials)
|
||||||
|
throw new TRPCError({
|
||||||
|
code: 'NOT_FOUND',
|
||||||
|
message: 'No credentials found',
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = (await decrypt(
|
||||||
|
credentials.data,
|
||||||
|
credentials.iv
|
||||||
|
)) as ZemanticAiCredentials['data']
|
||||||
|
|
||||||
|
const url = 'https://api.zemantic.ai/v1/projects'
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await got
|
||||||
|
.get(url, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${data.apiKey}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.json()
|
||||||
|
|
||||||
|
const projectsData = response as {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
}[]
|
||||||
|
|
||||||
|
return {
|
||||||
|
projects: projectsData.map((project) => ({
|
||||||
|
label: project.name,
|
||||||
|
value: project.id,
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: 'INTERNAL_SERVER_ERROR',
|
||||||
|
message: 'Could not list projects',
|
||||||
|
cause: e,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { router } from '@/helpers/server/trpc'
|
||||||
|
import { listProjects } from './listProjects'
|
||||||
|
|
||||||
|
export const zemanticAiRouter = router({
|
||||||
|
listProjects,
|
||||||
|
})
|
||||||
@@ -8,7 +8,7 @@ import { smtpCredentialsSchema } from '@typebot.io/schemas/features/blocks/integ
|
|||||||
import { encrypt } from '@typebot.io/lib/api/encryption'
|
import { encrypt } from '@typebot.io/lib/api/encryption'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { whatsAppCredentialsSchema } from '@typebot.io/schemas/features/whatsapp'
|
import { whatsAppCredentialsSchema } from '@typebot.io/schemas/features/whatsapp'
|
||||||
import { Credentials } from '@typebot.io/schemas'
|
import { Credentials, zemanticAiCredentialsSchema } from '@typebot.io/schemas'
|
||||||
import { isDefined } from '@typebot.io/lib/utils'
|
import { isDefined } from '@typebot.io/lib/utils'
|
||||||
import { isWriteWorkspaceForbidden } from '@/features/workspace/helpers/isWriteWorkspaceForbidden'
|
import { isWriteWorkspaceForbidden } from '@/features/workspace/helpers/isWriteWorkspaceForbidden'
|
||||||
|
|
||||||
@@ -37,6 +37,7 @@ export const createCredentials = authenticatedProcedure
|
|||||||
googleSheetsCredentialsSchema.pick(inputShape),
|
googleSheetsCredentialsSchema.pick(inputShape),
|
||||||
openAICredentialsSchema.pick(inputShape),
|
openAICredentialsSchema.pick(inputShape),
|
||||||
whatsAppCredentialsSchema.pick(inputShape),
|
whatsAppCredentialsSchema.pick(inputShape),
|
||||||
|
zemanticAiCredentialsSchema.pick(inputShape),
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { smtpCredentialsSchema } from '@typebot.io/schemas/features/blocks/integ
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { isReadWorkspaceFobidden } from '@/features/workspace/helpers/isReadWorkspaceFobidden'
|
import { isReadWorkspaceFobidden } from '@/features/workspace/helpers/isReadWorkspaceFobidden'
|
||||||
import { whatsAppCredentialsSchema } from '@typebot.io/schemas/features/whatsapp'
|
import { whatsAppCredentialsSchema } from '@typebot.io/schemas/features/whatsapp'
|
||||||
|
import { zemanticAiCredentialsSchema } from '@typebot.io/schemas/features/blocks/integrations/zemanticAi'
|
||||||
|
|
||||||
export const listCredentials = authenticatedProcedure
|
export const listCredentials = authenticatedProcedure
|
||||||
.meta({
|
.meta({
|
||||||
@@ -26,7 +27,8 @@ export const listCredentials = authenticatedProcedure
|
|||||||
.or(smtpCredentialsSchema.shape.type)
|
.or(smtpCredentialsSchema.shape.type)
|
||||||
.or(googleSheetsCredentialsSchema.shape.type)
|
.or(googleSheetsCredentialsSchema.shape.type)
|
||||||
.or(openAICredentialsSchema.shape.type)
|
.or(openAICredentialsSchema.shape.type)
|
||||||
.or(whatsAppCredentialsSchema.shape.type),
|
.or(whatsAppCredentialsSchema.shape.type)
|
||||||
|
.or(zemanticAiCredentialsSchema.shape.type),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.output(
|
.output(
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import { TypebotLinkIcon } from '@/features/blocks/logic/typebotLink/components/
|
|||||||
import { AbTestIcon } from '@/features/blocks/logic/abTest/components/AbTestIcon'
|
import { AbTestIcon } from '@/features/blocks/logic/abTest/components/AbTestIcon'
|
||||||
import { PictureChoiceIcon } from '@/features/blocks/inputs/pictureChoice/components/PictureChoiceIcon'
|
import { PictureChoiceIcon } from '@/features/blocks/inputs/pictureChoice/components/PictureChoiceIcon'
|
||||||
import { PixelLogo } from '@/features/blocks/integrations/pixel/components/PixelLogo'
|
import { PixelLogo } from '@/features/blocks/integrations/pixel/components/PixelLogo'
|
||||||
|
import { ZemanticAiLogo } from '@/features/blocks/integrations/zemanticAi/ZemanticAiLogo'
|
||||||
|
|
||||||
type BlockIconProps = { type: BlockType } & IconProps
|
type BlockIconProps = { type: BlockType } & IconProps
|
||||||
|
|
||||||
@@ -118,6 +119,8 @@ export const BlockIcon = ({ type, ...props }: BlockIconProps): JSX.Element => {
|
|||||||
return <OpenAILogo fill={openAIColor} {...props} />
|
return <OpenAILogo fill={openAIColor} {...props} />
|
||||||
case IntegrationBlockType.PIXEL:
|
case IntegrationBlockType.PIXEL:
|
||||||
return <PixelLogo {...props} />
|
return <PixelLogo {...props} />
|
||||||
|
case IntegrationBlockType.ZEMANTIC_AI:
|
||||||
|
return <ZemanticAiLogo {...props} />
|
||||||
case 'start':
|
case 'start':
|
||||||
return <FlagIcon {...props} />
|
return <FlagIcon {...props} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,5 +84,7 @@ export const BlockLabel = ({ type }: Props): JSX.Element => {
|
|||||||
return <Text fontSize="sm">{scopedT('openai.label')}</Text>
|
return <Text fontSize="sm">{scopedT('openai.label')}</Text>
|
||||||
case IntegrationBlockType.PIXEL:
|
case IntegrationBlockType.PIXEL:
|
||||||
return <Text fontSize="sm">{scopedT('pixel.label')}</Text>
|
return <Text fontSize="sm">{scopedT('pixel.label')}</Text>
|
||||||
|
case IntegrationBlockType.ZEMANTIC_AI:
|
||||||
|
return <Text fontSize="sm">{scopedT('zemanticAi.label')}</Text>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import { AbTestNodeBody } from '@/features/blocks/logic/abTest/components/AbTest
|
|||||||
import { PictureChoiceNode } from '@/features/blocks/inputs/pictureChoice/components/PictureChoiceNode'
|
import { PictureChoiceNode } from '@/features/blocks/inputs/pictureChoice/components/PictureChoiceNode'
|
||||||
import { PixelNodeBody } from '@/features/blocks/integrations/pixel/components/PixelNodeBody'
|
import { PixelNodeBody } from '@/features/blocks/integrations/pixel/components/PixelNodeBody'
|
||||||
import { useScopedI18n } from '@/locales'
|
import { useScopedI18n } from '@/locales'
|
||||||
|
import { ZemanticAiNodeBody } from '@/features/blocks/integrations/zemanticAi/ZemanticAiNodeBody'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
block: Block | StartBlock
|
block: Block | StartBlock
|
||||||
@@ -200,6 +201,9 @@ export const BlockNodeContent = ({ block, indices }: Props): JSX.Element => {
|
|||||||
case IntegrationBlockType.PIXEL: {
|
case IntegrationBlockType.PIXEL: {
|
||||||
return <PixelNodeBody options={block.options} />
|
return <PixelNodeBody options={block.options} />
|
||||||
}
|
}
|
||||||
|
case IntegrationBlockType.ZEMANTIC_AI: {
|
||||||
|
return <ZemanticAiNodeBody options={block.options} />
|
||||||
|
}
|
||||||
case 'start': {
|
case 'start': {
|
||||||
return <Text>{scopedT('text')}</Text>
|
return <Text>{scopedT('text')}</Text>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import { AbTestSettings } from '@/features/blocks/logic/abTest/components/AbTest
|
|||||||
import { PictureChoiceSettings } from '@/features/blocks/inputs/pictureChoice/components/PictureChoiceSettings'
|
import { PictureChoiceSettings } from '@/features/blocks/inputs/pictureChoice/components/PictureChoiceSettings'
|
||||||
import { SettingsHoverBar } from './SettingsHoverBar'
|
import { SettingsHoverBar } from './SettingsHoverBar'
|
||||||
import { PixelSettings } from '@/features/blocks/integrations/pixel/components/PixelSettings'
|
import { PixelSettings } from '@/features/blocks/integrations/pixel/components/PixelSettings'
|
||||||
|
import { ZemanticAiSettings } from '@/features/blocks/integrations/zemanticAi/ZemanticAiSettings'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
block: BlockWithOptions
|
block: BlockWithOptions
|
||||||
@@ -314,5 +315,10 @@ export const BlockSettings = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
case IntegrationBlockType.ZEMANTIC_AI: {
|
||||||
|
return (
|
||||||
|
<ZemanticAiSettings block={block} onOptionsChange={updateOptions} />
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,5 +63,7 @@ export const getHelpDocUrl = (blockType: BlockWithOptions['type']): string => {
|
|||||||
return 'https://docs.typebot.io/editor/blocks/logic/jump'
|
return 'https://docs.typebot.io/editor/blocks/logic/jump'
|
||||||
case IntegrationBlockType.PIXEL:
|
case IntegrationBlockType.PIXEL:
|
||||||
return 'https://docs.typebot.io/editor/blocks/integrations/pixel'
|
return 'https://docs.typebot.io/editor/blocks/integrations/pixel'
|
||||||
|
case IntegrationBlockType.ZEMANTIC_AI:
|
||||||
|
return 'https://docs.typebot.io/editor/blocks/integrations/zemantic-ai'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import {
|
|||||||
defaultAbTestOptions,
|
defaultAbTestOptions,
|
||||||
BlockWithItems,
|
BlockWithItems,
|
||||||
defaultTypebotLinkOptions,
|
defaultTypebotLinkOptions,
|
||||||
|
zemanticAiDefaultOptions,
|
||||||
} from '@typebot.io/schemas'
|
} from '@typebot.io/schemas'
|
||||||
import { defaultPictureChoiceOptions } from '@typebot.io/schemas/features/blocks/inputs/pictureChoice'
|
import { defaultPictureChoiceOptions } from '@typebot.io/schemas/features/blocks/inputs/pictureChoice'
|
||||||
|
|
||||||
@@ -143,6 +144,8 @@ const parseDefaultBlockOptions = (type: BlockWithOptionsType): BlockOptions => {
|
|||||||
return {}
|
return {}
|
||||||
case IntegrationBlockType.PIXEL:
|
case IntegrationBlockType.PIXEL:
|
||||||
return {}
|
return {}
|
||||||
|
case IntegrationBlockType.ZEMANTIC_AI:
|
||||||
|
return zemanticAiDefaultOptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { customDomainsRouter } from '@/features/customDomains/api/router'
|
|||||||
import { whatsAppRouter } from '@/features/whatsapp/router'
|
import { whatsAppRouter } from '@/features/whatsapp/router'
|
||||||
import { openAIRouter } from '@/features/blocks/integrations/openai/api/router'
|
import { openAIRouter } from '@/features/blocks/integrations/openai/api/router'
|
||||||
import { generateUploadUrl } from '@/features/upload/api/generateUploadUrl'
|
import { generateUploadUrl } from '@/features/upload/api/generateUploadUrl'
|
||||||
|
import { zemanticAiRouter } from '@/features/blocks/integrations/zemanticAi/api/router'
|
||||||
|
|
||||||
export const trpcRouter = router({
|
export const trpcRouter = router({
|
||||||
getAppVersionProcedure,
|
getAppVersionProcedure,
|
||||||
@@ -35,6 +36,7 @@ export const trpcRouter = router({
|
|||||||
whatsApp: whatsAppRouter,
|
whatsApp: whatsAppRouter,
|
||||||
openAI: openAIRouter,
|
openAI: openAIRouter,
|
||||||
generateUploadUrl,
|
generateUploadUrl,
|
||||||
|
zemanticAi: zemanticAiRouter,
|
||||||
})
|
})
|
||||||
|
|
||||||
export type AppRouter = typeof trpcRouter
|
export type AppRouter = typeof trpcRouter
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ export default {
|
|||||||
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
'editor.sidebarBlock.openai.label': 'OpenAI',
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
'editor.sidebarBlock.pixel.label': 'Pixel',
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.sidebarBlock.zemanticAi.label': 'Zemantic AI',
|
||||||
'editor.blockCard.bubbleBlock.tooltip.label':
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
'Ein PDF, ein iframe, eine Website einbetten...',
|
'Ein PDF, ein iframe, eine Website einbetten...',
|
||||||
'editor.blockCard.inputBlock.tooltip.files.label': 'Dateien hochladen',
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Dateien hochladen',
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ export default {
|
|||||||
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
'editor.sidebarBlock.openai.label': 'OpenAI',
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
'editor.sidebarBlock.pixel.label': 'Pixel',
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.sidebarBlock.zemanticAi.label': 'Zemantic AI',
|
||||||
'editor.blockCard.bubbleBlock.tooltip.label':
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
'Embed a pdf, an iframe, a website...',
|
'Embed a pdf, an iframe, a website...',
|
||||||
'editor.blockCard.inputBlock.tooltip.files.label': 'Upload Files',
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Upload Files',
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ export default {
|
|||||||
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
'editor.sidebarBlock.openai.label': 'OpenAI',
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
'editor.sidebarBlock.pixel.label': 'Pixel',
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.sidebarBlock.zemanticAi.label': 'Zemantic AI',
|
||||||
'editor.blockCard.bubbleBlock.tooltip.label':
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
'Intégrer un pdf, un iframe, un site web...',
|
'Intégrer un pdf, un iframe, un site web...',
|
||||||
'editor.blockCard.inputBlock.tooltip.files.label': 'Télécharger des fichiers',
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Télécharger des fichiers',
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ export default {
|
|||||||
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
'editor.sidebarBlock.openai.label': 'OpenAI',
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
'editor.sidebarBlock.pixel.label': 'Pixel',
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.sidebarBlock.zemanticAi.label': 'Zemantic AI',
|
||||||
'editor.blockCard.bubbleBlock.tooltip.label':
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
'Incorporar pdf, iframe, website...',
|
'Incorporar pdf, iframe, website...',
|
||||||
'editor.blockCard.inputBlock.tooltip.files.label': 'Carregar Ficheiros',
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Carregar Ficheiros',
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ export default {
|
|||||||
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
'editor.sidebarBlock.chatwoot.label': 'Chatwoot',
|
||||||
'editor.sidebarBlock.openai.label': 'OpenAI',
|
'editor.sidebarBlock.openai.label': 'OpenAI',
|
||||||
'editor.sidebarBlock.pixel.label': 'Pixel',
|
'editor.sidebarBlock.pixel.label': 'Pixel',
|
||||||
|
'editor.sidebarBlock.zemanticAi.label': 'Zemantic AI',
|
||||||
'editor.blockCard.bubbleBlock.tooltip.label':
|
'editor.blockCard.bubbleBlock.tooltip.label':
|
||||||
'Incorporar pdf, iframe, website...',
|
'Incorporar pdf, iframe, website...',
|
||||||
'editor.blockCard.inputBlock.tooltip.files.label': 'Carregar Ficheiros',
|
'editor.blockCard.inputBlock.tooltip.files.label': 'Carregar Ficheiros',
|
||||||
|
|||||||
44
apps/docs/docs/editor/blocks/integrations/zemantic-ai.mdx
Normal file
44
apps/docs/docs/editor/blocks/integrations/zemantic-ai.mdx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Zemantic AI
|
||||||
|
|
||||||
|
With the Zemantic AI block, you can search and retrieve results or LLM summaries from your documents stored on Zemantic AI.
|
||||||
|
|
||||||
|
<img
|
||||||
|
src="/img/blocks/integrations/zemanticAi/overview.png"
|
||||||
|
width="600"
|
||||||
|
alt="OpenAI block"
|
||||||
|
/>
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
This integration requires a Zemantic AI account. If you don't have one yet, you can create one [here](https://zemantic.ai/).
|
||||||
|
|
||||||
|
The block has the following settings:
|
||||||
|
|
||||||
|
<img
|
||||||
|
src="/img/blocks/integrations/zemanticAi/settings.png"
|
||||||
|
width="600"
|
||||||
|
alt="OpenAI messages sequence"
|
||||||
|
/>
|
||||||
|
|
||||||
|
- Zemantic AI account: create or select the Zemantic AI credentials you want to use.
|
||||||
|
- Project ID: The project id of the project containing the documents you want to search
|
||||||
|
- Question or Query: The question you want to ask your Zemantic AI documents
|
||||||
|
- Max Results: The maximum number of results you want to retrieve
|
||||||
|
|
||||||
|
### Prompt Settings
|
||||||
|
|
||||||
|
- System Prompt: The prompt you want to use to guide the LLM behavior
|
||||||
|
- Prompt: The prompt you want to use to summarize your documents
|
||||||
|
|
||||||
|
## Troobleshooting
|
||||||
|
|
||||||
|
### Error message: "Zemantic AI block returned error"
|
||||||
|
|
||||||
|
It means your Zemantic AI block is not configured properly. Please check the following:
|
||||||
|
|
||||||
|
- You have selected an Zemantic AI account
|
||||||
|
- You have filled out the Question or Query field
|
||||||
|
|
||||||
|
### It returns an empty message
|
||||||
|
|
||||||
|
Either you misconfigured the block or your may have have gone over the context limits of the LLM. You can try lowering the number of results to retrieve or shortening your prompt.
|
||||||
@@ -3906,6 +3906,88 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groupId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outgoingEdgeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Zemantic AI"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"credentialsId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"systemPrompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maxResults": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"responseMapping": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"valueToExtract": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Summary",
|
||||||
|
"Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variableId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"responseMapping"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"groupId",
|
||||||
|
"type",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -8211,6 +8293,88 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groupId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outgoingEdgeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Zemantic AI"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"credentialsId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"systemPrompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maxResults": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"responseMapping": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"valueToExtract": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Summary",
|
||||||
|
"Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variableId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"responseMapping"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"groupId",
|
||||||
|
"type",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -12151,6 +12315,88 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groupId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outgoingEdgeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Zemantic AI"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"credentialsId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"systemPrompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maxResults": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"responseMapping": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"valueToExtract": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Summary",
|
||||||
|
"Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variableId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"responseMapping"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"groupId",
|
||||||
|
"type",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -16231,6 +16477,88 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groupId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outgoingEdgeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Zemantic AI"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"credentialsId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"systemPrompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maxResults": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"responseMapping": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"valueToExtract": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Summary",
|
||||||
|
"Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variableId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"responseMapping"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"groupId",
|
||||||
|
"type",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -20191,6 +20519,88 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groupId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outgoingEdgeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Zemantic AI"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"credentialsId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"systemPrompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maxResults": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"responseMapping": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"valueToExtract": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Summary",
|
||||||
|
"Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variableId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"responseMapping"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"groupId",
|
||||||
|
"type",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -24206,6 +24616,88 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groupId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outgoingEdgeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Zemantic AI"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"credentialsId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"systemPrompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maxResults": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"responseMapping": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"valueToExtract": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Summary",
|
||||||
|
"Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variableId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"responseMapping"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"groupId",
|
||||||
|
"type",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -28284,6 +28776,88 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groupId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outgoingEdgeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Zemantic AI"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"credentialsId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"systemPrompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maxResults": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"responseMapping": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"valueToExtract": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Summary",
|
||||||
|
"Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variableId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"responseMapping"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"groupId",
|
||||||
|
"type",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -30536,6 +31110,42 @@
|
|||||||
"name"
|
"name"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"apiKey": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"apiKey"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"zemanticAi"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"workspaceId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"data",
|
||||||
|
"type",
|
||||||
|
"workspaceId",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -30604,6 +31214,8 @@
|
|||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
@@ -30643,6 +31255,14 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"zemanticAi"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -32356,6 +32976,78 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/zemantic-ai/projects": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "zemanticAi-listProjects",
|
||||||
|
"summary": "List Zemantic AI projects",
|
||||||
|
"tags": [
|
||||||
|
"ZemanticAi"
|
||||||
|
],
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"Authorization": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "credentialsId",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "workspaceId",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"projects": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"label": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"label",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"projects"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/components/responses/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
|
|||||||
@@ -3489,6 +3489,88 @@
|
|||||||
"options"
|
"options"
|
||||||
],
|
],
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"groupId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"outgoingEdgeId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Zemantic AI"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blockId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"credentialsId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"projectId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"systemPrompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"query": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"maxResults": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"responseMapping": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"valueToExtract": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Summary",
|
||||||
|
"Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variableId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"responseMapping"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"groupId",
|
||||||
|
"type",
|
||||||
|
"options"
|
||||||
|
],
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
apps/docs/static/img/blocks/integrations/zemanticAi/overview.png
vendored
Normal file
BIN
apps/docs/static/img/blocks/integrations/zemanticAi/overview.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
BIN
apps/docs/static/img/blocks/integrations/zemanticAi/settings.png
vendored
Normal file
BIN
apps/docs/static/img/blocks/integrations/zemanticAi/settings.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
@@ -0,0 +1,129 @@
|
|||||||
|
import { ExecuteIntegrationResponse } from '@/features/chat/types'
|
||||||
|
import prisma from '@/lib/prisma'
|
||||||
|
import { SessionState } from '@typebot.io/schemas'
|
||||||
|
import {
|
||||||
|
ZemanticAiBlock,
|
||||||
|
ZemanticAiCredentials,
|
||||||
|
ZemanticAiResponse,
|
||||||
|
} from '@typebot.io/schemas/features/blocks/integrations/zemanticAi'
|
||||||
|
import got from 'got'
|
||||||
|
import { decrypt } from '@typebot.io/lib/api/encryption'
|
||||||
|
import { byId, isDefined, isEmpty } from '@typebot.io/lib'
|
||||||
|
import { updateVariables } from '@/features/variables/updateVariables'
|
||||||
|
import { getDefinedVariables, parseAnswers } from '@typebot.io/lib/results'
|
||||||
|
|
||||||
|
const URL = 'https://api.zemantic.ai/v1/search-documents'
|
||||||
|
|
||||||
|
export const executeZemanticAiBlock = async (
|
||||||
|
state: SessionState,
|
||||||
|
block: ZemanticAiBlock
|
||||||
|
): Promise<ExecuteIntegrationResponse> => {
|
||||||
|
let newSessionState = state
|
||||||
|
|
||||||
|
const noCredentialsError = {
|
||||||
|
status: 'error',
|
||||||
|
description: 'Make sure to select a Zemantic AI account',
|
||||||
|
}
|
||||||
|
|
||||||
|
const zemanticRequestError = {
|
||||||
|
status: 'error',
|
||||||
|
description: 'Could not execute Zemantic AI request',
|
||||||
|
}
|
||||||
|
|
||||||
|
const credentials = await prisma.credentials.findUnique({
|
||||||
|
where: {
|
||||||
|
id: block.options.credentialsId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if (!credentials) {
|
||||||
|
console.error('Could not find credentials in database')
|
||||||
|
return {
|
||||||
|
outgoingEdgeId: block.outgoingEdgeId,
|
||||||
|
logs: [noCredentialsError],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const { apiKey } = (await decrypt(
|
||||||
|
credentials.data,
|
||||||
|
credentials.iv
|
||||||
|
)) as ZemanticAiCredentials['data']
|
||||||
|
|
||||||
|
const { typebot, answers } = newSessionState.typebotsQueue[0]
|
||||||
|
|
||||||
|
const templateVars = parseAnswers({
|
||||||
|
variables: getDefinedVariables(typebot.variables),
|
||||||
|
answers: answers,
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res: ZemanticAiResponse = await got
|
||||||
|
.post(URL, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${apiKey}`,
|
||||||
|
},
|
||||||
|
json: {
|
||||||
|
projectId: block.options.projectId,
|
||||||
|
query: replaceTemplateVars(
|
||||||
|
block.options.query as string,
|
||||||
|
templateVars
|
||||||
|
),
|
||||||
|
maxResults: block.options.maxResults,
|
||||||
|
summarize: true,
|
||||||
|
summaryOptions: {
|
||||||
|
system_prompt:
|
||||||
|
replaceTemplateVars(
|
||||||
|
block.options.systemPrompt as string,
|
||||||
|
templateVars
|
||||||
|
) ?? '',
|
||||||
|
prompt:
|
||||||
|
replaceTemplateVars(
|
||||||
|
block.options.prompt as string,
|
||||||
|
templateVars
|
||||||
|
) ?? '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.json()
|
||||||
|
|
||||||
|
for (const r of block.options.responseMapping || []) {
|
||||||
|
const variable = typebot.variables.find(byId(r.variableId))
|
||||||
|
switch (r.valueToExtract) {
|
||||||
|
case 'Summary':
|
||||||
|
if (isDefined(variable) && !isEmpty(res.summary)) {
|
||||||
|
newSessionState = updateVariables(newSessionState)([
|
||||||
|
{ ...variable, value: res.summary },
|
||||||
|
])
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'Results':
|
||||||
|
if (isDefined(variable) && res.results.length) {
|
||||||
|
newSessionState = updateVariables(newSessionState)([
|
||||||
|
{ ...variable, value: JSON.stringify(res.results) },
|
||||||
|
])
|
||||||
|
}
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
return {
|
||||||
|
outgoingEdgeId: block.outgoingEdgeId,
|
||||||
|
logs: [zemanticRequestError],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { outgoingEdgeId: block.outgoingEdgeId, newSessionState }
|
||||||
|
}
|
||||||
|
|
||||||
|
const replaceTemplateVars = (
|
||||||
|
template: string,
|
||||||
|
vars: Record<string, string>
|
||||||
|
) => {
|
||||||
|
if (!template) return
|
||||||
|
let result = template
|
||||||
|
for (const [key, value] of Object.entries(vars)) {
|
||||||
|
result = result.replaceAll(`{{${key}}}`, value)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import { executeChatwootBlock } from '@/features/blocks/integrations/chatwoot/ex
|
|||||||
import { executeGoogleAnalyticsBlock } from '@/features/blocks/integrations/googleAnalytics/executeGoogleAnalyticsBlock'
|
import { executeGoogleAnalyticsBlock } from '@/features/blocks/integrations/googleAnalytics/executeGoogleAnalyticsBlock'
|
||||||
import { executeGoogleSheetBlock } from '@/features/blocks/integrations/googleSheets/executeGoogleSheetBlock'
|
import { executeGoogleSheetBlock } from '@/features/blocks/integrations/googleSheets/executeGoogleSheetBlock'
|
||||||
import { executePixelBlock } from '@/features/blocks/integrations/pixel/executePixelBlock'
|
import { executePixelBlock } from '@/features/blocks/integrations/pixel/executePixelBlock'
|
||||||
|
import { executeZemanticAiBlock } from '@/features/blocks/integrations/zemanticAi/executeZemanticAiBlock'
|
||||||
import {
|
import {
|
||||||
IntegrationBlock,
|
IntegrationBlock,
|
||||||
IntegrationBlockType,
|
IntegrationBlockType,
|
||||||
@@ -33,5 +34,7 @@ export const executeIntegration =
|
|||||||
return executeOpenAIBlock(state, block)
|
return executeOpenAIBlock(state, block)
|
||||||
case IntegrationBlockType.PIXEL:
|
case IntegrationBlockType.PIXEL:
|
||||||
return executePixelBlock(state, block)
|
return executePixelBlock(state, block)
|
||||||
|
case IntegrationBlockType.ZEMANTIC_AI:
|
||||||
|
return executeZemanticAiBlock(state, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ export enum IntegrationBlockType {
|
|||||||
PABBLY_CONNECT = 'Pabbly',
|
PABBLY_CONNECT = 'Pabbly',
|
||||||
CHATWOOT = 'Chatwoot',
|
CHATWOOT = 'Chatwoot',
|
||||||
PIXEL = 'Pixel',
|
PIXEL = 'Pixel',
|
||||||
|
ZEMANTIC_AI = 'Zemantic AI',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,3 +9,4 @@ export * from './webhook/schemas'
|
|||||||
export * from './zapier'
|
export * from './zapier'
|
||||||
export * from './pixel/schemas'
|
export * from './pixel/schemas'
|
||||||
export * from './pixel/constants'
|
export * from './pixel/constants'
|
||||||
|
export * from './zemanticAi'
|
||||||
|
|||||||
62
packages/schemas/features/blocks/integrations/zemanticAi.ts
Normal file
62
packages/schemas/features/blocks/integrations/zemanticAi.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { z } from 'zod'
|
||||||
|
import { blockBaseSchema, credentialsBaseSchema } from '../baseSchemas'
|
||||||
|
import { IntegrationBlockType } from './enums'
|
||||||
|
|
||||||
|
export const searchResponseValues = ['Summary', 'Results'] as const
|
||||||
|
|
||||||
|
export const zemanticAiOptionsSchema = z.object({
|
||||||
|
credentialsId: z.string().optional(),
|
||||||
|
projectId: z.string().optional(),
|
||||||
|
systemPrompt: z.string().optional(),
|
||||||
|
prompt: z.string().optional(),
|
||||||
|
query: z.string().optional(),
|
||||||
|
maxResults: z.number().int().optional(),
|
||||||
|
responseMapping: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
valueToExtract: z.preprocess(
|
||||||
|
(val) => (!val ? 'Summary' : val),
|
||||||
|
z.enum(searchResponseValues)
|
||||||
|
),
|
||||||
|
variableId: z.string().optional(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const zemanticAiBlockSchema = blockBaseSchema.merge(
|
||||||
|
z.object({
|
||||||
|
type: z.enum([IntegrationBlockType.ZEMANTIC_AI]),
|
||||||
|
blockId: z.string().optional(),
|
||||||
|
options: zemanticAiOptionsSchema,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
export const zemanticAiCredentialsSchema = z
|
||||||
|
.object({
|
||||||
|
type: z.literal('zemanticAi'),
|
||||||
|
data: z.object({
|
||||||
|
apiKey: z.string(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.merge(credentialsBaseSchema)
|
||||||
|
|
||||||
|
export const zemanticSearchResponseSchema = z.object({
|
||||||
|
results: z.array(
|
||||||
|
z.object({
|
||||||
|
documentId: z.string(),
|
||||||
|
text: z.string(),
|
||||||
|
score: z.number(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
summary: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const zemanticAiDefaultOptions: ZemanticAiOptions = {
|
||||||
|
maxResults: 3,
|
||||||
|
responseMapping: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ZemanticAiResponse = z.infer<typeof zemanticSearchResponseSchema>
|
||||||
|
export type ZemanticAiCredentials = z.infer<typeof zemanticAiCredentialsSchema>
|
||||||
|
export type ZemanticAiOptions = z.infer<typeof zemanticAiOptionsSchema>
|
||||||
|
export type ZemanticAiBlock = z.infer<typeof zemanticAiBlockSchema>
|
||||||
@@ -48,6 +48,7 @@ import {
|
|||||||
import { jumpBlockSchema } from './logic/jump'
|
import { jumpBlockSchema } from './logic/jump'
|
||||||
import { pictureChoiceBlockSchema } from './inputs/pictureChoice'
|
import { pictureChoiceBlockSchema } from './inputs/pictureChoice'
|
||||||
import { Item } from '../items'
|
import { Item } from '../items'
|
||||||
|
import { zemanticAiBlockSchema } from './integrations/zemanticAi'
|
||||||
|
|
||||||
export type DraggableBlock =
|
export type DraggableBlock =
|
||||||
| BubbleBlock
|
| BubbleBlock
|
||||||
@@ -127,6 +128,7 @@ export const blockSchema = z.discriminatedUnion('type', [
|
|||||||
webhookBlockSchema,
|
webhookBlockSchema,
|
||||||
zapierBlockSchema,
|
zapierBlockSchema,
|
||||||
pixelBlockSchema,
|
pixelBlockSchema,
|
||||||
|
zemanticAiBlockSchema,
|
||||||
])
|
])
|
||||||
|
|
||||||
export type Block = z.infer<typeof blockSchema>
|
export type Block = z.infer<typeof blockSchema>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { googleSheetsCredentialsSchema } from './blocks/integrations/googleSheet
|
|||||||
import { openAICredentialsSchema } from './blocks/integrations/openai'
|
import { openAICredentialsSchema } from './blocks/integrations/openai'
|
||||||
import { smtpCredentialsSchema } from './blocks/integrations/sendEmail'
|
import { smtpCredentialsSchema } from './blocks/integrations/sendEmail'
|
||||||
import { whatsAppCredentialsSchema } from './whatsapp'
|
import { whatsAppCredentialsSchema } from './whatsapp'
|
||||||
|
import { zemanticAiCredentialsSchema } from './blocks'
|
||||||
|
|
||||||
export const credentialsSchema = z.discriminatedUnion('type', [
|
export const credentialsSchema = z.discriminatedUnion('type', [
|
||||||
smtpCredentialsSchema,
|
smtpCredentialsSchema,
|
||||||
@@ -11,6 +12,7 @@ export const credentialsSchema = z.discriminatedUnion('type', [
|
|||||||
stripeCredentialsSchema,
|
stripeCredentialsSchema,
|
||||||
openAICredentialsSchema,
|
openAICredentialsSchema,
|
||||||
whatsAppCredentialsSchema,
|
whatsAppCredentialsSchema,
|
||||||
|
zemanticAiCredentialsSchema,
|
||||||
])
|
])
|
||||||
|
|
||||||
export type Credentials = z.infer<typeof credentialsSchema>
|
export type Credentials = z.infer<typeof credentialsSchema>
|
||||||
|
|||||||
Reference in New Issue
Block a user