2
0

🐛 (openai) Fix models dropdown list on new block

This commit is contained in:
Baptiste Arnaud
2023-09-08 17:16:15 +02:00
parent 75e4b16af0
commit 096262cff9
4 changed files with 22 additions and 52 deletions

View File

@ -5,15 +5,17 @@ import { z } from 'zod'
import { isReadWorkspaceFobidden } from '@/features/workspace/helpers/isReadWorkspaceFobidden' import { isReadWorkspaceFobidden } from '@/features/workspace/helpers/isReadWorkspaceFobidden'
import { Configuration, OpenAIApi, ResponseTypes } from 'openai-edge' import { Configuration, OpenAIApi, ResponseTypes } from 'openai-edge'
import { decrypt } from '@typebot.io/lib/api' import { decrypt } from '@typebot.io/lib/api'
import { OpenAICredentials } from '@typebot.io/schemas/features/blocks/integrations/openai' import {
import { IntegrationBlockType, typebotSchema } from '@typebot.io/schemas' OpenAICredentials,
defaultBaseUrl,
} from '@typebot.io/schemas/features/blocks/integrations/openai'
import { isNotEmpty } from '@typebot.io/lib/utils' import { isNotEmpty } from '@typebot.io/lib/utils'
export const listModels = authenticatedProcedure export const listModels = authenticatedProcedure
.meta({ .meta({
openapi: { openapi: {
method: 'GET', method: 'GET',
path: '/typebots/{typebotId}/blocks/{blockId}/openai/models', path: '/openai/models',
protect: true, protect: true,
summary: 'List OpenAI models', summary: 'List OpenAI models',
tags: ['OpenAI'], tags: ['OpenAI'],
@ -21,10 +23,10 @@ export const listModels = authenticatedProcedure
}) })
.input( .input(
z.object({ z.object({
typebotId: z.string(),
blockId: z.string(),
credentialsId: z.string(), credentialsId: z.string(),
workspaceId: z.string(), workspaceId: z.string(),
baseUrl: z.string().default(defaultBaseUrl),
apiVersion: z.string().optional(),
}) })
) )
.output( .output(
@ -34,7 +36,7 @@ export const listModels = authenticatedProcedure
) )
.query( .query(
async ({ async ({
input: { credentialsId, workspaceId, typebotId, blockId }, input: { credentialsId, workspaceId, baseUrl, apiVersion },
ctx: { user }, ctx: { user },
}) => { }) => {
const workspace = await prisma.workspace.findFirst({ const workspace = await prisma.workspace.findFirst({
@ -45,14 +47,6 @@ export const listModels = authenticatedProcedure
userId: true, userId: true,
}, },
}, },
typebots: {
where: {
id: typebotId,
},
select: {
groups: true,
},
},
credentials: { credentials: {
where: { where: {
id: credentialsId, id: credentialsId,
@ -80,25 +74,6 @@ export const listModels = authenticatedProcedure
message: 'No credentials found', message: 'No credentials found',
}) })
const typebot = workspace.typebots.at(0)
if (!typebot)
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Typebot not found',
})
const block = typebotSchema._def.schema.shape.groups
.parse(workspace.typebots.at(0)?.groups)
.flatMap((group) => group.blocks)
.find((block) => block.id === blockId)
if (!block || block.type !== IntegrationBlockType.OPEN_AI)
throw new TRPCError({
code: 'NOT_FOUND',
message: 'OpenAI block not found',
})
const data = (await decrypt( const data = (await decrypt(
credentials.data, credentials.data,
credentials.iv credentials.iv
@ -106,15 +81,15 @@ export const listModels = authenticatedProcedure
const config = new Configuration({ const config = new Configuration({
apiKey: data.apiKey, apiKey: data.apiKey,
basePath: block.options.baseUrl, basePath: baseUrl,
baseOptions: { baseOptions: {
headers: { headers: {
'api-key': data.apiKey, 'api-key': data.apiKey,
}, },
}, },
defaultQueryParams: isNotEmpty(block.options.apiVersion) defaultQueryParams: isNotEmpty(apiVersion)
? new URLSearchParams({ ? new URLSearchParams({
'api-version': block.options.apiVersion, 'api-version': apiVersion,
}) })
: undefined, : undefined,
}) })

View File

@ -33,7 +33,7 @@ type Props = {
} }
export const OpenAISettings = ({ export const OpenAISettings = ({
block: { options, id }, block: { options },
onOptionsChange, onOptionsChange,
}: Props) => { }: Props) => {
const { workspace } = useWorkspace() const { workspace } = useWorkspace()
@ -126,7 +126,6 @@ export const OpenAISettings = ({
/> />
{options.task && ( {options.task && (
<OpenAITaskSettings <OpenAITaskSettings
blockId={id}
options={options} options={options}
onOptionsChange={onOptionsChange} onOptionsChange={onOptionsChange}
/> />
@ -140,24 +139,21 @@ export const OpenAISettings = ({
const OpenAITaskSettings = ({ const OpenAITaskSettings = ({
options, options,
onOptionsChange, onOptionsChange,
blockId,
}: { }: {
options: ChatCompletionOpenAIOptions | CreateImageOpenAIOptions options: ChatCompletionOpenAIOptions | CreateImageOpenAIOptions
blockId: string
onOptionsChange: (options: OpenAIBlock['options']) => void onOptionsChange: (options: OpenAIBlock['options']) => void
}) => { }) => {
switch (options.task) { switch (options.task) {
case 'Create chat completion': { case 'Create chat completion': {
return ( return (
<OpenAIChatCompletionSettings <OpenAIChatCompletionSettings
blockId={blockId}
options={options} options={options}
onOptionsChange={onOptionsChange} onOptionsChange={onOptionsChange}
/> />
) )
} }
case 'Create image': { case 'Create image': {
return <></> return null
} }
} }
} }

View File

@ -1,35 +1,35 @@
import { Select } from '@/components/inputs/Select' import { Select } from '@/components/inputs/Select'
import { useTypebot } from '@/features/editor/providers/TypebotProvider'
import { useWorkspace } from '@/features/workspace/WorkspaceProvider' import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
import { useToast } from '@/hooks/useToast' import { useToast } from '@/hooks/useToast'
import { trpc } from '@/lib/trpc' import { trpc } from '@/lib/trpc'
type Props = { type Props = {
baseUrl: string
apiVersion?: string
credentialsId: string credentialsId: string
blockId: string
defaultValue: string defaultValue: string
onChange: (model: string | undefined) => void onChange: (model: string | undefined) => void
} }
export const ModelsDropdown = ({ export const ModelsDropdown = ({
baseUrl,
apiVersion,
defaultValue, defaultValue,
onChange, onChange,
credentialsId, credentialsId,
blockId,
}: Props) => { }: Props) => {
const { typebot } = useTypebot()
const { workspace } = useWorkspace() const { workspace } = useWorkspace()
const { showToast } = useToast() const { showToast } = useToast()
const { data } = trpc.openAI.listModels.useQuery( const { data } = trpc.openAI.listModels.useQuery(
{ {
credentialsId, credentialsId,
blockId, baseUrl,
typebotId: typebot?.id as string,
workspaceId: workspace?.id as string, workspaceId: workspace?.id as string,
apiVersion,
}, },
{ {
enabled: !!typebot && !!workspace, enabled: !!workspace,
onError: (error) => { onError: (error) => {
showToast({ showToast({
description: error.message, description: error.message,

View File

@ -19,13 +19,11 @@ const apiReferenceUrl =
'https://platform.openai.com/docs/api-reference/chat/create' 'https://platform.openai.com/docs/api-reference/chat/create'
type Props = { type Props = {
blockId: string
options: ChatCompletionOpenAIOptions options: ChatCompletionOpenAIOptions
onOptionsChange: (options: ChatCompletionOpenAIOptions) => void onOptionsChange: (options: ChatCompletionOpenAIOptions) => void
} }
export const OpenAIChatCompletionSettings = ({ export const OpenAIChatCompletionSettings = ({
blockId,
options, options,
onOptionsChange, onOptionsChange,
}: Props) => { }: Props) => {
@ -79,8 +77,9 @@ export const OpenAIChatCompletionSettings = ({
<ModelsDropdown <ModelsDropdown
credentialsId={options.credentialsId} credentialsId={options.credentialsId}
defaultValue={options.model} defaultValue={options.model}
baseUrl={options.baseUrl}
apiVersion={options.apiVersion}
onChange={updateModel} onChange={updateModel}
blockId={blockId}
/> />
<Accordion allowMultiple> <Accordion allowMultiple>
<AccordionItem> <AccordionItem>