2
0

Remove ZemanticAI block

Closes #1656, closes #1652
This commit is contained in:
Baptiste Arnaud
2024-07-22 17:24:02 +02:00
parent 71d09cdf7c
commit ec2a53fac1
50 changed files with 5 additions and 1821 deletions

View File

@ -1,47 +0,0 @@
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"
/>
)
}

View File

@ -1,44 +0,0 @@
import { DropdownList } from '@/components/DropdownList'
import { VariableSearchInput } from '@/components/inputs/VariableSearchInput'
import { TableListItemProps } from '@/components/TableList'
import { Stack } from '@chakra-ui/react'
import { Variable, ZemanticAiBlock } from '@typebot.io/schemas'
import {
defaultZemanticAiResponseMappingItem,
searchResponseValues,
} from '@typebot.io/schemas/features/blocks/integrations/zemanticAi/constants'
type Props = TableListItemProps<
NonNullable<
NonNullable<ZemanticAiBlock['options']>['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 ??
defaultZemanticAiResponseMappingItem.valueToExtract
}
items={searchResponseValues}
onItemSelect={changeValueToExtract}
/>
<VariableSearchInput
onSelectVariable={changeVariableId}
initialVariableId={item.variableId}
/>
</Stack>
)
}

View File

@ -1,21 +0,0 @@
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>
)

View File

@ -1,37 +0,0 @@
import React from 'react'
import { Stack, Text } from '@chakra-ui/react'
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
import { SetVariableLabel } from '@/components/SetVariableLabel'
import { ZemanticAiBlock } from '@typebot.io/schemas'
type Props = {
options: ZemanticAiBlock['options']
}
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>
)
}

View File

@ -1,148 +0,0 @@
import { TextInput, Textarea, NumberInput } from '@/components/inputs'
import {
Accordion,
AccordionButton,
AccordionIcon,
AccordionItem,
AccordionPanel,
Stack,
Text,
} from '@chakra-ui/react'
import { isEmpty } from '@typebot.io/lib'
import { ZemanticAiBlock } from '@typebot.io/schemas'
import { ProjectsDropdown } from './ProjectsDropdown'
import { SearchResponseItem } from './SearchResponseItem'
import { TableList } from '@/components/TableList'
type Props = {
block: ZemanticAiBlock
onOptionsChange: (options: ZemanticAiBlock['options']) => void
}
export const ZemanticAiSettings = ({
block: { id: blockId, options },
onOptionsChange,
}: Props) => {
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: NonNullable<ZemanticAiBlock['options']>['responseMapping']
) => {
onOptionsChange({
...options,
responseMapping,
})
}
return (
<Stack spacing={4}>
{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 ?? []}
onItemsChange={updateResponseMapping}
newItemDefaultProps={{ valueToExtract: 'Summary' }}
>
{(props) => <SearchResponseItem {...props} />}
</TableList>
</AccordionPanel>
</AccordionItem>
</Accordion>
</>
)}
</Stack>
)
}

View File

@ -1,87 +0,0 @@
import prisma from '@typebot.io/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/encryption/decrypt'
import { ZemanticAiCredentials } from '@typebot.io/schemas/features/blocks/integrations/zemanticAi'
import ky from 'ky'
export const listProjects = authenticatedProcedure
.input(
z.object({
credentialsId: z.string(),
workspaceId: 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 ky
.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,
})
}
})

View File

@ -1,6 +0,0 @@
import { router } from '@/helpers/server/trpc'
import { listProjects } from './listProjects'
export const zemanticAiRouter = router({
listProjects,
})

View File

@ -62,8 +62,6 @@ const CredentialsCreateModalContent = ({
onClose={onClose} onClose={onClose}
/> />
) )
case 'zemanticAi':
return null
default: default:
return ( return (
<CreateForgedCredentialsModalContent <CreateForgedCredentialsModalContent

View File

@ -211,8 +211,6 @@ const CredentialsIcon = ({
return <StripeLogo rounded="sm" {...props} /> return <StripeLogo rounded="sm" {...props} />
case 'whatsApp': case 'whatsApp':
return <WhatsAppLogo {...props} /> return <WhatsAppLogo {...props} />
case 'zemanticAi':
return null
default: default:
return <BlockIcon type={type} {...props} /> return <BlockIcon type={type} {...props} />
} }
@ -247,8 +245,6 @@ const CredentialsLabel = ({
WhatsApp WhatsApp
</Text> </Text>
) )
case 'zemanticAi':
return null
default: default:
return <BlockLabel type={type} {...props} /> return <BlockLabel type={type} {...props} />
} }

View File

@ -57,7 +57,6 @@ const CredentialsUpdateModalContent = ({
onUpdate={onSubmit} onUpdate={onSubmit}
/> />
) )
case 'zemanticAi':
case 'whatsApp': case 'whatsApp':
return null return null
default: default:

View File

@ -31,7 +31,6 @@ 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'
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants' import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants' import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants' import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants'
@ -117,8 +116,6 @@ export const BlockIcon = ({ type, ...props }: BlockIconProps): JSX.Element => {
return <ChatwootLogo {...props} /> return <ChatwootLogo {...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} />
case IntegrationBlockType.OPEN_AI: case IntegrationBlockType.OPEN_AI:

View File

@ -219,12 +219,6 @@ export const BlockLabel = ({ type, ...props }: Props): JSX.Element => {
{t('editor.sidebarBlock.pixel.label')} {t('editor.sidebarBlock.pixel.label')}
</Text> </Text>
) )
case IntegrationBlockType.ZEMANTIC_AI:
return (
<Text fontSize="sm" {...props}>
{t('editor.sidebarBlock.zemanticAi.label')}
</Text>
)
default: default:
return <ForgedBlockLabel type={type} {...props} /> return <ForgedBlockLabel type={type} {...props} />
} }

View File

@ -27,10 +27,7 @@ import { useDebouncedCallback } from 'use-debounce'
import { forgedBlockIds } from '@typebot.io/forge-repository/constants' import { forgedBlockIds } from '@typebot.io/forge-repository/constants'
// Integration blocks migrated to forged blocks // Integration blocks migrated to forged blocks
const legacyIntegrationBlocks = [ const legacyIntegrationBlocks = [IntegrationBlockType.OPEN_AI]
IntegrationBlockType.OPEN_AI,
IntegrationBlockType.ZEMANTIC_AI,
]
export const BlocksSideBar = () => { export const BlocksSideBar = () => {
const { t } = useTranslate() const { t } = useTranslate()

View File

@ -16,7 +16,7 @@ import {
import React, { useState } from 'react' import React, { useState } from 'react'
import { ZodObjectLayout } from '../zodLayouts/ZodObjectLayout' import { ZodObjectLayout } from '../zodLayouts/ZodObjectLayout'
import { ForgedBlockDefinition } from '@typebot.io/forge-repository/types' import { ForgedBlockDefinition } from '@typebot.io/forge-repository/types'
import { CredentialsWithoutLegacy } from '@typebot.io/schemas' import { Credentials } from '@typebot.io/schemas'
type Props = { type Props = {
blockDef: ForgedBlockDefinition blockDef: ForgedBlockDefinition
@ -91,7 +91,7 @@ export const CreateForgedCredentialsModalContent = ({
workspaceId: workspace.id, workspaceId: workspace.id,
name, name,
data, data,
} as CredentialsWithoutLegacy, } as Credentials,
}) })
} }

View File

@ -14,7 +14,7 @@ import {
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { ZodObjectLayout } from '../zodLayouts/ZodObjectLayout' import { ZodObjectLayout } from '../zodLayouts/ZodObjectLayout'
import { ForgedBlockDefinition } from '@typebot.io/forge-repository/types' import { ForgedBlockDefinition } from '@typebot.io/forge-repository/types'
import { CredentialsWithoutLegacy } from '@typebot.io/schemas' import { Credentials } from '@typebot.io/schemas'
type Props = { type Props = {
credentialsId: string credentialsId: string
@ -76,7 +76,7 @@ export const UpdateForgedCredentialsModalContent = ({
workspaceId: workspace.id, workspaceId: workspace.id,
name, name,
data, data,
} as CredentialsWithoutLegacy, } as Credentials,
}) })
} }

View File

@ -32,7 +32,6 @@ import { ChatwootNodeBody } from '@/features/blocks/integrations/chatwoot/compon
import { AbTestNodeBody } from '@/features/blocks/logic/abTest/components/AbTestNodeBody' import { AbTestNodeBody } from '@/features/blocks/logic/abTest/components/AbTestNodeBody'
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 { ZemanticAiNodeBody } from '@/features/blocks/integrations/zemanticAi/ZemanticAiNodeBody'
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants' import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants' import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants' import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
@ -151,9 +150,6 @@ export const BlockNodeContent = ({
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} />
}
default: { default: {
return <ForgedBlockNodeContent block={block} indices={indices} /> return <ForgedBlockNodeContent block={block} indices={indices} />
} }

View File

@ -39,7 +39,6 @@ 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'
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants' import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants' import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants'
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants' import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
@ -338,11 +337,6 @@ export const BlockSettings = ({
/> />
) )
} }
case IntegrationBlockType.ZEMANTIC_AI: {
return (
<ZemanticAiSettings block={block} onOptionsChange={updateOptions} />
)
}
case LogicBlockType.CONDITION: case LogicBlockType.CONDITION:
return null return null
default: { default: {

View File

@ -65,8 +65,6 @@ export const getHelpDocUrl = (
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'
case LogicBlockType.CONDITION: case LogicBlockType.CONDITION:
return 'https://docs.typebot.io/editor/blocks/logic/condition' return 'https://docs.typebot.io/editor/blocks/logic/condition'
default: default:

View File

@ -3,7 +3,6 @@ import { router } from '../trpc'
import { generateUploadUrl } from '@/features/upload/api/generateUploadUrl' import { generateUploadUrl } from '@/features/upload/api/generateUploadUrl'
import { openAIRouter } from '@/features/blocks/integrations/openai/api/router' import { openAIRouter } from '@/features/blocks/integrations/openai/api/router'
import { internalWhatsAppRouter } from '@/features/whatsapp/router' import { internalWhatsAppRouter } from '@/features/whatsapp/router'
import { zemanticAiRouter } from '@/features/blocks/integrations/zemanticAi/api/router'
import { forgeRouter } from '@/features/forge/api/router' import { forgeRouter } from '@/features/forge/api/router'
import { googleSheetsRouter } from '@/features/blocks/integrations/googleSheets/api/router' import { googleSheetsRouter } from '@/features/blocks/integrations/googleSheets/api/router'
import { telemetryRouter } from '@/features/telemetry/api/router' import { telemetryRouter } from '@/features/telemetry/api/router'
@ -13,7 +12,6 @@ export const internalRouter = router({
generateUploadUrl, generateUploadUrl,
whatsAppInternal: internalWhatsAppRouter, whatsAppInternal: internalWhatsAppRouter,
openAI: openAIRouter, openAI: openAIRouter,
zemanticAI: zemanticAiRouter,
forge: forgeRouter, forge: forgeRouter,
sheets: googleSheetsRouter, sheets: googleSheetsRouter,
telemetry: telemetryRouter, telemetry: telemetryRouter,

View File

@ -1,48 +0,0 @@
---
title: Zemantic AI
---
With the Zemantic AI block, you can search and retrieve results or LLM summaries from your documents stored on Zemantic AI.
<Frame>
<img
src="/images/blocks/integrations/zemanticAi/overview.png"
alt="Zemantic AI block"
/>
</Frame>
## 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:
<Frame>
<img
src="/images/blocks/integrations/zemanticAi/settings.png"
alt="Zemantic AI settings"
/>
</Frame>
- 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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

View File

@ -122,7 +122,6 @@
"editor/blocks/integrations/chatwoot", "editor/blocks/integrations/chatwoot",
"editor/blocks/integrations/meta-pixel", "editor/blocks/integrations/meta-pixel",
"editor/blocks/integrations/openai", "editor/blocks/integrations/openai",
"editor/blocks/integrations/zemantic-ai",
"editor/blocks/integrations/mistral", "editor/blocks/integrations/mistral",
"editor/blocks/integrations/elevenlabs", "editor/blocks/integrations/elevenlabs",
"editor/blocks/integrations/anthropic", "editor/blocks/integrations/anthropic",

View File

@ -2469,78 +2469,6 @@
"id", "id",
"type" "type"
] ]
},
{
"type": "object",
"properties": {
"id": {
"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",
"valueToExtract"
]
}
}
}
}
},
"required": [
"id",
"type"
]
} }
] ]
} }
@ -6838,78 +6766,6 @@
"id", "id",
"type" "type"
] ]
},
{
"type": "object",
"properties": {
"id": {
"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",
"valueToExtract"
]
}
}
}
}
},
"required": [
"id",
"type"
]
} }
] ]
} }
@ -10344,78 +10200,6 @@
"id", "id",
"type" "type"
] ]
},
{
"type": "object",
"properties": {
"id": {
"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",
"valueToExtract"
]
}
}
}
}
},
"required": [
"id",
"type"
]
} }
] ]
} }
@ -12949,37 +12733,6 @@
"name" "name"
] ]
}, },
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"apiKey": {
"type": "string"
}
}
},
"type": {
"type": "string",
"enum": [
"zemantic-ai"
]
},
"workspaceId": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"data",
"type",
"workspaceId",
"name"
]
},
{ {
"type": "object", "type": "object",
"properties": { "properties": {
@ -13345,9 +13098,7 @@
"google sheets", "google sheets",
"stripe", "stripe",
"whatsApp", "whatsApp",
"zemanticAi",
"openai", "openai",
"zemantic-ai",
"chat-node", "chat-node",
"dify-ai", "dify-ai",
"mistral", "mistral",
@ -13383,9 +13134,7 @@
"google sheets", "google sheets",
"stripe", "stripe",
"whatsApp", "whatsApp",
"zemanticAi",
"openai", "openai",
"zemantic-ai",
"chat-node", "chat-node",
"dify-ai", "dify-ai",
"mistral", "mistral",
@ -13836,37 +13585,6 @@
"workspaceId" "workspaceId"
] ]
}, },
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"apiKey": {
"type": "string"
}
}
},
"type": {
"type": "string",
"enum": [
"zemantic-ai"
]
},
"workspaceId": {
"type": "string"
}
},
"required": [
"name",
"data",
"type",
"workspaceId"
]
},
{ {
"type": "object", "type": "object",
"properties": { "properties": {
@ -19821,78 +19539,6 @@
"type" "type"
] ]
}, },
{
"type": "object",
"properties": {
"id": {
"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",
"valueToExtract"
]
}
}
}
}
},
"required": [
"id",
"type"
]
},
{ {
"type": "object", "type": "object",
"properties": { "properties": {
@ -20462,99 +20108,6 @@
"type" "type"
] ]
}, },
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"outgoingEdgeId": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"zemantic-ai"
]
},
"options": {
"oneOf": [
{
"type": "object",
"properties": {
"projectId": {
"type": "string"
},
"credentialsId": {
"type": "string"
}
}
},
{
"type": "object",
"properties": {
"projectId": {
"type": "string"
},
"credentialsId": {
"type": "string"
},
"action": {
"type": "string",
"enum": [
"Search documents"
]
},
"query": {
"type": "string"
},
"maxResults": {
"anyOf": [
{
"type": "number"
},
{}
]
},
"systemPrompt": {
"type": "string"
},
"prompt": {
"type": "string"
},
"responseMapping": {
"type": "array",
"items": {
"type": "object",
"properties": {
"item": {
"type": "string",
"enum": [
"Summary",
"Document IDs",
"Texts",
"Scores"
]
},
"variableId": {
"type": "string"
}
}
}
}
},
"required": [
"action"
]
}
]
}
},
"required": [
"id",
"type"
]
},
{ {
"type": "object", "type": "object",
"properties": { "properties": {
@ -26532,78 +26085,6 @@
"id", "id",
"type" "type"
] ]
},
{
"type": "object",
"properties": {
"id": {
"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",
"valueToExtract"
]
}
}
}
}
},
"required": [
"id",
"type"
]
} }
] ]
} }
@ -29407,78 +28888,6 @@
"id", "id",
"type" "type"
] ]
},
{
"type": "object",
"properties": {
"id": {
"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",
"valueToExtract"
]
}
}
}
}
},
"required": [
"id",
"type"
]
} }
] ]
} }

View File

@ -5753,78 +5753,6 @@
"id", "id",
"type" "type"
] ]
},
{
"type": "object",
"properties": {
"id": {
"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",
"valueToExtract"
]
}
}
}
}
},
"required": [
"id",
"type"
]
} }
] ]
} }
@ -9888,78 +9816,6 @@
"type" "type"
] ]
}, },
{
"type": "object",
"properties": {
"id": {
"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",
"valueToExtract"
]
}
}
}
}
},
"required": [
"id",
"type"
]
},
{ {
"type": "object", "type": "object",
"properties": { "properties": {
@ -10529,99 +10385,6 @@
"type" "type"
] ]
}, },
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"outgoingEdgeId": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"zemantic-ai"
]
},
"options": {
"oneOf": [
{
"type": "object",
"properties": {
"projectId": {
"type": "string"
},
"credentialsId": {
"type": "string"
}
}
},
{
"type": "object",
"properties": {
"projectId": {
"type": "string"
},
"credentialsId": {
"type": "string"
},
"action": {
"type": "string",
"enum": [
"Search documents"
]
},
"query": {
"type": "string"
},
"maxResults": {
"anyOf": [
{
"type": "number"
},
{}
]
},
"systemPrompt": {
"type": "string"
},
"prompt": {
"type": "string"
},
"responseMapping": {
"type": "array",
"items": {
"type": "object",
"properties": {
"item": {
"type": "string",
"enum": [
"Summary",
"Document IDs",
"Texts",
"Scores"
]
},
"variableId": {
"type": "string"
}
}
}
}
},
"required": [
"action"
]
}
]
}
},
"required": [
"id",
"type"
]
},
{ {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -1,147 +0,0 @@
import { SessionState } from '@typebot.io/schemas'
import {
ZemanticAiBlock,
ZemanticAiCredentials,
ZemanticAiResponse,
} from '@typebot.io/schemas/features/blocks/integrations/zemanticAi'
import ky from 'ky'
import { decrypt } from '@typebot.io/lib/api/encryption/decrypt'
import { byId, isDefined, isEmpty } from '@typebot.io/lib'
import { ExecuteIntegrationResponse } from '../../../types'
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
import { getCredentials } from '../../../queries/getCredentials'
import { parseAnswers } from '@typebot.io/results/parseAnswers'
const URL = 'https://api.zemantic.ai/v1/search-documents'
export const executeZemanticAiBlock = async (
state: SessionState,
block: ZemanticAiBlock
): Promise<ExecuteIntegrationResponse> => {
let newSessionState = state
let setVariableHistory = []
if (!block.options?.credentialsId)
return {
outgoingEdgeId: block.outgoingEdgeId,
}
const credentials = await getCredentials(block.options.credentialsId)
if (!credentials) {
return {
outgoingEdgeId: block.outgoingEdgeId,
logs: [
{
status: 'error',
description: 'Make sure to select a Zemantic AI account',
},
],
}
}
const { apiKey } = (await decrypt(
credentials.data,
credentials.iv
)) as ZemanticAiCredentials['data']
const { typebot, answers } = newSessionState.typebotsQueue[0]
const templateVars = parseAnswers({
variables: typebot.variables,
answers: answers,
})
try {
const res: ZemanticAiResponse = await ky
.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))
let newVariables = []
switch (r.valueToExtract) {
case 'Summary':
if (isDefined(variable) && !isEmpty(res.summary)) {
newVariables.push({ ...variable, value: res.summary })
}
break
case 'Results':
if (isDefined(variable) && res.results.length) {
newVariables.push({
...variable,
value: JSON.stringify(res.results),
})
}
break
default:
break
}
if (newVariables.length > 0) {
const { newSetVariableHistory, updatedState } =
updateVariablesInSession({
newVariables,
state: newSessionState,
currentBlockId: block.id,
})
newSessionState = updatedState
setVariableHistory.push(...newSetVariableHistory)
}
}
} catch (e) {
console.error(e)
return {
startTimeShouldBeUpdated: true,
outgoingEdgeId: block.outgoingEdgeId,
logs: [
{
status: 'error',
description: 'Could not execute Zemantic AI request',
},
],
newSetVariableHistory: setVariableHistory,
}
}
return {
outgoingEdgeId: block.outgoingEdgeId,
newSessionState,
startTimeShouldBeUpdated: true,
}
}
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
}

View File

@ -4,7 +4,6 @@ import { executeChatwootBlock } from './blocks/integrations/chatwoot/executeChat
import { executeGoogleAnalyticsBlock } from './blocks/integrations/legacy/googleAnalytics/executeGoogleAnalyticsBlock' import { executeGoogleAnalyticsBlock } from './blocks/integrations/legacy/googleAnalytics/executeGoogleAnalyticsBlock'
import { executeGoogleSheetBlock } from './blocks/integrations/googleSheets/executeGoogleSheetBlock' import { executeGoogleSheetBlock } from './blocks/integrations/googleSheets/executeGoogleSheetBlock'
import { executePixelBlock } from './blocks/integrations/pixel/executePixelBlock' import { executePixelBlock } from './blocks/integrations/pixel/executePixelBlock'
import { executeZemanticAiBlock } from './blocks/integrations/zemanticAi/executeZemanticAiBlock'
import { IntegrationBlock, SessionState } from '@typebot.io/schemas' import { IntegrationBlock, SessionState } from '@typebot.io/schemas'
import { ExecuteIntegrationResponse } from './types' import { ExecuteIntegrationResponse } from './types'
import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants' import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants'
@ -50,11 +49,6 @@ export const executeIntegration =
} }
case IntegrationBlockType.PIXEL: case IntegrationBlockType.PIXEL:
return executePixelBlock(state, block) return executePixelBlock(state, block)
case IntegrationBlockType.ZEMANTIC_AI:
return {
...(await executeZemanticAiBlock(state, block)),
startTimeShouldBeUpdated: true,
}
default: default:
return { return {
...(await executeForgedBlock(state, block)), ...(await executeForgedBlock(state, block)),

View File

@ -1,110 +0,0 @@
import { createAction, option } from '@typebot.io/forge'
import { isDefined } from '@typebot.io/lib'
import { ZemanticAiResponse } from '../types'
import ky from 'ky'
import { apiBaseUrl } from '../constants'
import { auth } from '../auth'
import { baseOptions } from '../baseOptions'
export const searchDocuments = createAction({
baseOptions,
auth,
name: 'Search documents',
options: option.object({
query: option.string.layout({
label: 'Query',
placeholder: 'Content',
moreInfoTooltip:
'The question you want to ask or search against the documents in the project.',
}),
maxResults: option.number.layout({
label: 'Max results',
placeholder: 'i.e. 3',
defaultValue: 3,
moreInfoTooltip:
'The maximum number of document chunk results to return from your search.',
}),
systemPrompt: option.string.layout({
accordion: 'Advanced settings',
label: 'System prompt',
moreInfoTooltip:
'System prompt to send to the summarization LLM. This is prepended to the prompt and helps guide system behavior.',
inputType: 'textarea',
}),
prompt: option.string.layout({
accordion: 'Advanced settings',
label: 'Prompt',
moreInfoTooltip: 'Prompt to send to the summarization LLM.',
inputType: 'textarea',
}),
responseMapping: option
.saveResponseArray([
'Summary',
'Document IDs',
'Texts',
'Scores',
] as const)
.layout({
accordion: 'Save response',
}),
}),
getSetVariableIds: ({ responseMapping }) =>
responseMapping?.map((r) => r.variableId).filter(isDefined) ?? [],
run: {
server: async ({
credentials: { apiKey },
options: {
maxResults,
projectId,
prompt,
query,
responseMapping,
systemPrompt,
},
variables,
}) => {
const res = await ky
.post(apiBaseUrl, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
json: {
projectId,
query,
maxResults,
summarize: true,
summaryOptions: {
system_prompt: systemPrompt,
prompt: prompt,
},
},
})
.json<ZemanticAiResponse>()
responseMapping?.forEach((mapping) => {
if (!mapping.variableId || !mapping.item) return
if (mapping.item === 'Document IDs')
variables.set(
mapping.variableId,
res.results.map((r) => r.documentId)
)
if (mapping.item === 'Texts')
variables.set(
mapping.variableId,
res.results.map((r) => r.text)
)
if (mapping.item === 'Scores')
variables.set(
mapping.variableId,
res.results.map((r) => r.score)
)
if (mapping.item === 'Summary')
variables.set(mapping.variableId, res.summary)
})
},
},
})

View File

@ -1,17 +0,0 @@
import { AuthDefinition, option } from '@typebot.io/forge'
export const auth = {
type: 'encryptedCredentials',
name: 'Zemantic AI account',
schema: option.object({
apiKey: option.string.layout({
label: 'API key',
isRequired: true,
placeholder: 'ze...',
inputType: 'password',
helperText:
'You can generate an API key [here](https://zemantic.ai/dashboard/settings).',
isDebounceDisabled: true,
}),
}),
} satisfies AuthDefinition

View File

@ -1,8 +0,0 @@
import { option } from '@typebot.io/forge'
export const baseOptions = option.object({
projectId: option.string.layout({
placeholder: 'Select a project',
fetcher: 'fetchProjects',
}),
})

View File

@ -1 +0,0 @@
export const apiBaseUrl = 'https://api.zemantic.ai/v1/search-documents'

View File

@ -1,45 +0,0 @@
import { createBlock } from '@typebot.io/forge'
import { ZemanticAiLogo } from './logo'
import ky from 'ky'
import { searchDocuments } from './actions/searchDocuments'
import { auth } from './auth'
import { baseOptions } from './baseOptions'
export const zemanticAiBlock = createBlock({
id: 'zemantic-ai',
name: 'Zemantic AI',
tags: [],
LightLogo: ZemanticAiLogo,
auth,
options: baseOptions,
fetchers: [
{
id: 'fetchProjects',
dependencies: [],
fetch: async ({ credentials }) => {
if (!credentials?.apiKey) return []
const url = 'https://api.zemantic.ai/v1/projects'
const response = await ky
.get(url, {
headers: {
Authorization: `Bearer ${credentials.apiKey}`,
},
})
.json()
const projectsData = response as {
id: string
name: string
}[]
return projectsData.map((project) => ({
label: project.name,
value: project.id,
}))
},
},
],
actions: [searchDocuments],
})

View File

@ -1,21 +0,0 @@
/** @jsxImportSource react */
export const ZemanticAiLogo = (props: React.SVGProps<SVGSVGElement>) => (
<svg 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>
</svg>
)

View File

@ -1,16 +0,0 @@
{
"name": "@typebot.io/zemantic-ai-block",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"keywords": [],
"license": "AGPL-3.0-or-later",
"devDependencies": {
"@typebot.io/forge": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.4.5",
"@typebot.io/lib": "workspace:*",
"ky": "1.2.4"
}
}

View File

@ -1,10 +0,0 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { zemanticAiBlock } from '.'
import { auth } from './auth'
export const zemanticAiBlockSchema = parseBlockSchema(zemanticAiBlock)
export const zemanticAiCredentialsSchema = parseBlockCredentials(
zemanticAiBlock.id,
auth.schema
)

View File

@ -1,11 +0,0 @@
{
"extends": "@typebot.io/tsconfig/base.json",
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"],
"compilerOptions": {
"lib": ["ESNext", "DOM"],
"noEmit": true,
"jsx": "preserve",
"jsxImportSource": "react"
}
}

View File

@ -1,4 +0,0 @@
export type ZemanticAiResponse = {
results: { documentId: string; text: string; score: number }[]
summary: string
}

View File

@ -3,7 +3,6 @@ import { ForgedBlock } from './types'
export const forgedBlockIds = [ export const forgedBlockIds = [
'openai', 'openai',
'zemantic-ai',
'cal-com', 'cal-com',
'chat-node', 'chat-node',
'qr-code', 'qr-code',

View File

@ -14,14 +14,11 @@ import { openAIBlock } from '@typebot.io/openai-block'
import { openAICredentialsSchema } from '@typebot.io/openai-block/schemas' import { openAICredentialsSchema } from '@typebot.io/openai-block/schemas'
import { togetherAiBlock } from '@typebot.io/together-ai-block' import { togetherAiBlock } from '@typebot.io/together-ai-block'
import { togetherAiCredentialsSchema } from '@typebot.io/together-ai-block/schemas' import { togetherAiCredentialsSchema } from '@typebot.io/together-ai-block/schemas'
import { zemanticAiBlock } from '@typebot.io/zemantic-ai-block'
import { zemanticAiCredentialsSchema } from '@typebot.io/zemantic-ai-block/schemas'
import { nocodbBlock } from '@typebot.io/nocodb-block' import { nocodbBlock } from '@typebot.io/nocodb-block'
import { nocodbCredentialsSchema } from '@typebot.io/nocodb-block/schemas' import { nocodbCredentialsSchema } from '@typebot.io/nocodb-block/schemas'
export const forgedCredentialsSchemas = { export const forgedCredentialsSchemas = {
[openAIBlock.id]: openAICredentialsSchema, [openAIBlock.id]: openAICredentialsSchema,
[zemanticAiBlock.id]: zemanticAiCredentialsSchema,
[chatNodeBlock.id]: chatNodeCredentialsSchema, [chatNodeBlock.id]: chatNodeCredentialsSchema,
[difyAiBlock.id]: difyAiCredentialsSchema, [difyAiBlock.id]: difyAiCredentialsSchema,
[mistralBlock.id]: mistralCredentialsSchema, [mistralBlock.id]: mistralCredentialsSchema,

View File

@ -8,13 +8,11 @@ import { mistralBlock } from '@typebot.io/mistral-block'
import { qrCodeBlock } from '@typebot.io/qrcode-block' import { qrCodeBlock } from '@typebot.io/qrcode-block'
import { chatNodeBlock } from '@typebot.io/chat-node-block' import { chatNodeBlock } from '@typebot.io/chat-node-block'
import { calComBlock } from '@typebot.io/cal-com-block' import { calComBlock } from '@typebot.io/cal-com-block'
import { zemanticAiBlock } from '@typebot.io/zemantic-ai-block'
import { openAIBlock } from '@typebot.io/openai-block' import { openAIBlock } from '@typebot.io/openai-block'
import { nocodbBlock } from '@typebot.io/nocodb-block' import { nocodbBlock } from '@typebot.io/nocodb-block'
export const forgedBlocks = { export const forgedBlocks = {
[openAIBlock.id]: openAIBlock, [openAIBlock.id]: openAIBlock,
[zemanticAiBlock.id]: zemanticAiBlock,
[calComBlock.id]: calComBlock, [calComBlock.id]: calComBlock,
[chatNodeBlock.id]: chatNodeBlock, [chatNodeBlock.id]: chatNodeBlock,
[qrCodeBlock.id]: qrCodeBlock, [qrCodeBlock.id]: qrCodeBlock,

View File

@ -8,7 +8,6 @@
"devDependencies": { "devDependencies": {
"@typebot.io/forge": "workspace:*", "@typebot.io/forge": "workspace:*",
"@typebot.io/openai-block": "workspace:*", "@typebot.io/openai-block": "workspace:*",
"@typebot.io/zemantic-ai-block": "workspace:*",
"@typebot.io/cal-com-block": "workspace:*", "@typebot.io/cal-com-block": "workspace:*",
"@typebot.io/chat-node-block": "workspace:*", "@typebot.io/chat-node-block": "workspace:*",
"@typebot.io/qrcode-block": "workspace:*", "@typebot.io/qrcode-block": "workspace:*",

View File

@ -19,14 +19,11 @@ import { qrCodeBlock } from '@typebot.io/qrcode-block'
import { qrCodeBlockSchema } from '@typebot.io/qrcode-block/schemas' import { qrCodeBlockSchema } from '@typebot.io/qrcode-block/schemas'
import { togetherAiBlock } from '@typebot.io/together-ai-block' import { togetherAiBlock } from '@typebot.io/together-ai-block'
import { togetherAiBlockSchema } from '@typebot.io/together-ai-block/schemas' import { togetherAiBlockSchema } from '@typebot.io/together-ai-block/schemas'
import { zemanticAiBlock } from '@typebot.io/zemantic-ai-block'
import { zemanticAiBlockSchema } from '@typebot.io/zemantic-ai-block/schemas'
import { nocodbBlock } from '@typebot.io/nocodb-block' import { nocodbBlock } from '@typebot.io/nocodb-block'
import { nocodbBlockSchema } from '@typebot.io/nocodb-block/schemas' import { nocodbBlockSchema } from '@typebot.io/nocodb-block/schemas'
export const forgedBlockSchemas = { export const forgedBlockSchemas = {
[openAIBlock.id]: openAIBlockSchema, [openAIBlock.id]: openAIBlockSchema,
[zemanticAiBlock.id]: zemanticAiBlockSchema,
[calComBlock.id]: calComBlockSchema, [calComBlock.id]: calComBlockSchema,
[chatNodeBlock.id]: chatNodeBlockSchema, [chatNodeBlock.id]: chatNodeBlockSchema,
[qrCodeBlock.id]: qrCodeBlockSchema, [qrCodeBlock.id]: qrCodeBlockSchema,

View File

@ -9,5 +9,4 @@ export enum IntegrationBlockType {
PABBLY_CONNECT = 'Pabbly', PABBLY_CONNECT = 'Pabbly',
CHATWOOT = 'Chatwoot', CHATWOOT = 'Chatwoot',
PIXEL = 'Pixel', PIXEL = 'Pixel',
ZEMANTIC_AI = 'Zemantic AI',
} }

View File

@ -7,5 +7,4 @@ export * from './sendEmail'
export * from './webhook' export * from './webhook'
export * from './zapier' export * from './zapier'
export * from './pixel' export * from './pixel'
export * from './zemanticAi'
export * from './schema' export * from './schema'

View File

@ -5,7 +5,6 @@ import { googleSheetsBlockSchemas } from './googleSheets'
import { openAIBlockSchema } from './openai' import { openAIBlockSchema } from './openai'
import { pixelBlockSchema } from './pixel/schema' import { pixelBlockSchema } from './pixel/schema'
import { sendEmailBlockSchema } from './sendEmail' import { sendEmailBlockSchema } from './sendEmail'
import { zemanticAiBlockSchema } from './zemanticAi'
import { zapierBlockSchemas } from './zapier' import { zapierBlockSchemas } from './zapier'
import { httpBlockSchemas } from './webhook' import { httpBlockSchemas } from './webhook'
import { makeComBlockSchemas } from './makeCom' import { makeComBlockSchemas } from './makeCom'
@ -23,7 +22,6 @@ export const integrationBlockSchemas = {
httpBlockSchemas.v5, httpBlockSchemas.v5,
zapierBlockSchemas.v5, zapierBlockSchemas.v5,
pixelBlockSchema, pixelBlockSchema,
zemanticAiBlockSchema,
], ],
v6: [ v6: [
chatwootBlockSchema, chatwootBlockSchema,
@ -36,7 +34,6 @@ export const integrationBlockSchemas = {
httpBlockSchemas.v6, httpBlockSchemas.v6,
zapierBlockSchemas.v6, zapierBlockSchemas.v6,
pixelBlockSchema, pixelBlockSchema,
zemanticAiBlockSchema,
], ],
} as const } as const

View File

@ -1,11 +0,0 @@
import { ZemanticAiBlock } from './schema'
export const searchResponseValues = ['Summary', 'Results'] as const
export const defaultZemanticAiOptions = {
maxResults: 3,
} as const satisfies ZemanticAiBlock['options']
export const defaultZemanticAiResponseMappingItem = {
valueToExtract: 'Summary',
} as const

View File

@ -1 +0,0 @@
export * from './schema'

View File

@ -1,57 +0,0 @@
import { z } from '../../../../zod'
import { blockBaseSchema, credentialsBaseSchema } from '../../shared'
import { IntegrationBlockType } from '../constants'
import { searchResponseValues } from './constants'
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(),
})
)
.optional(),
})
export const zemanticAiBlockSchema = blockBaseSchema.merge(
z.object({
type: z.enum([IntegrationBlockType.ZEMANTIC_AI]),
blockId: z.string().optional(),
options: zemanticAiOptionsSchema.optional(),
})
)
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 type ZemanticAiResponse = z.infer<typeof zemanticSearchResponseSchema>
export type ZemanticAiCredentials = z.infer<typeof zemanticAiCredentialsSchema>
export type ZemanticAiBlock = z.infer<typeof zemanticAiBlockSchema>

View File

@ -1,5 +1,4 @@
import { z } from '../zod' import { z } from '../zod'
import { zemanticAiCredentialsSchema } from './blocks'
import { stripeCredentialsSchema } from './blocks/inputs/payment/schema' import { stripeCredentialsSchema } from './blocks/inputs/payment/schema'
import { googleSheetsCredentialsSchema } from './blocks/integrations/googleSheets/schema' import { googleSheetsCredentialsSchema } from './blocks/integrations/googleSheets/schema'
import { smtpCredentialsSchema } from './blocks/integrations/sendEmail' import { smtpCredentialsSchema } from './blocks/integrations/sendEmail'
@ -11,30 +10,19 @@ const credentialsSchema = z.discriminatedUnion('type', [
googleSheetsCredentialsSchema, googleSheetsCredentialsSchema,
stripeCredentialsSchema, stripeCredentialsSchema,
whatsAppCredentialsSchema, whatsAppCredentialsSchema,
zemanticAiCredentialsSchema,
...Object.values(forgedCredentialsSchemas), ...Object.values(forgedCredentialsSchemas),
]) ])
export type Credentials = z.infer<typeof credentialsSchema> export type Credentials = z.infer<typeof credentialsSchema>
export type CredentialsWithoutLegacy = Exclude<
Credentials,
{
type: 'zemanticAi'
}
>
export const credentialsTypes = [ export const credentialsTypes = [
'smtp', 'smtp',
'google sheets', 'google sheets',
'stripe', 'stripe',
'whatsApp', 'whatsApp',
'zemanticAi',
...(Object.keys(forgedCredentialsSchemas) as Array< ...(Object.keys(forgedCredentialsSchemas) as Array<
keyof typeof forgedCredentialsSchemas keyof typeof forgedCredentialsSchemas
>), >),
] as const ] as const
export const credentialsTypeSchema = z.enum(credentialsTypes) export const credentialsTypeSchema = z.enum(credentialsTypes)
export const legacyCredentialsTypes = ['zemanticAi']

24
pnpm-lock.yaml generated
View File

@ -1612,27 +1612,6 @@ importers:
specifier: 5.4.5 specifier: 5.4.5
version: 5.4.5 version: 5.4.5
packages/forge/blocks/zemanticAi:
devDependencies:
'@typebot.io/forge':
specifier: workspace:*
version: link:../../core
'@typebot.io/lib':
specifier: workspace:*
version: link:../../../lib
'@typebot.io/tsconfig':
specifier: workspace:*
version: link:../../../tsconfig
'@types/react':
specifier: 18.2.15
version: 18.2.15
ky:
specifier: 1.2.4
version: 1.2.4
typescript:
specifier: 5.4.5
version: 5.4.5
packages/forge/cli: packages/forge/cli:
devDependencies: devDependencies:
'@clack/prompts': '@clack/prompts':
@ -1702,9 +1681,6 @@ importers:
'@typebot.io/together-ai-block': '@typebot.io/together-ai-block':
specifier: workspace:* specifier: workspace:*
version: link:../blocks/togetherAi version: link:../blocks/togetherAi
'@typebot.io/zemantic-ai-block':
specifier: workspace:*
version: link:../blocks/zemanticAi
packages/lib: packages/lib:
dependencies: dependencies: