@@ -76,7 +76,7 @@
|
|||||||
"nextjs-cors": "2.1.2",
|
"nextjs-cors": "2.1.2",
|
||||||
"nodemailer": "6.9.3",
|
"nodemailer": "6.9.3",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"openai": "4.19.0",
|
"openai": "4.24.1",
|
||||||
"papaparse": "5.4.1",
|
"papaparse": "5.4.1",
|
||||||
"posthog-js": "1.77.1",
|
"posthog-js": "1.77.1",
|
||||||
"posthog-node": "3.1.1",
|
"posthog-node": "3.1.1",
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ type Props = {
|
|||||||
onOptionsChange: (options: BlockOptions) => void
|
onOptionsChange: (options: BlockOptions) => void
|
||||||
}
|
}
|
||||||
export const ForgedBlockSettings = ({ block, onOptionsChange }: Props) => {
|
export const ForgedBlockSettings = ({ block, onOptionsChange }: Props) => {
|
||||||
const { blockDef, blockSchema } = useForgedBlock(block.type)
|
const { blockDef, blockSchema, actionDef } = useForgedBlock(
|
||||||
|
block.type,
|
||||||
|
block.options?.action
|
||||||
|
)
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||||
|
|
||||||
const updateCredentialsId = (credentialsId?: string) => {
|
const updateCredentialsId = (credentialsId?: string) => {
|
||||||
@@ -22,6 +25,34 @@ export const ForgedBlockSettings = ({ block, onOptionsChange }: Props) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const resetOptionsAction = (updates: any) => {
|
||||||
|
if (!actionDef) return
|
||||||
|
const actionOptionsKeys = Object.keys(actionDef.options?.shape ?? [])
|
||||||
|
const actionOptions = actionOptionsKeys.reduce(
|
||||||
|
(acc, key) => ({
|
||||||
|
...acc,
|
||||||
|
[key]: undefined,
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
onOptionsChange({
|
||||||
|
...updates,
|
||||||
|
...actionOptions,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const updateOptions = (updates: any) => {
|
||||||
|
const isChangingAction =
|
||||||
|
actionDef && updates?.action && updates.action !== block.options.action
|
||||||
|
if (isChangingAction) {
|
||||||
|
resetOptionsAction(updates)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
onOptionsChange(updates)
|
||||||
|
}
|
||||||
|
|
||||||
if (!blockDef || !blockSchema) return null
|
if (!blockDef || !blockSchema) return null
|
||||||
return (
|
return (
|
||||||
<Stack spacing={4}>
|
<Stack spacing={4}>
|
||||||
@@ -57,7 +88,7 @@ export const ForgedBlockSettings = ({ block, onOptionsChange }: Props) => {
|
|||||||
schema={blockSchema.shape.options}
|
schema={blockSchema.shape.options}
|
||||||
blockDef={blockDef}
|
blockDef={blockDef}
|
||||||
blockOptions={block.options}
|
blockOptions={block.options}
|
||||||
onDataChange={onOptionsChange}
|
onDataChange={updateOptions}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -33,6 +33,17 @@ Then you can give the OpenAI block access to this sequence of messages:
|
|||||||
/>
|
/>
|
||||||
</Frame>
|
</Frame>
|
||||||
|
|
||||||
|
## Ask assistant
|
||||||
|
|
||||||
|
This action allows you to talk with your [OpenAI assistant](https://platform.openai.com/assistants). All you have to do is to provide its ID.
|
||||||
|
|
||||||
|
<Frame>
|
||||||
|
<img
|
||||||
|
src="/images/blocks/integrations/openai/ask-assistant.png"
|
||||||
|
alt="OpenAI ask assistant settings"
|
||||||
|
/>
|
||||||
|
</Frame>
|
||||||
|
|
||||||
## Create speech
|
## Create speech
|
||||||
|
|
||||||
This action allows you to transform a text input into an audio URL that you can reuse in your bot.
|
This action allows you to transform a text input into an audio URL that you can reuse in your bot.
|
||||||
|
|||||||
BIN
apps/docs/images/blocks/integrations/openai/ask-assistant.png
Normal file
BIN
apps/docs/images/blocks/integrations/openai/ask-assistant.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
@@ -26820,7 +26820,8 @@
|
|||||||
"openai",
|
"openai",
|
||||||
"zemantic-ai",
|
"zemantic-ai",
|
||||||
"cal-com",
|
"cal-com",
|
||||||
"chat-node"
|
"chat-node",
|
||||||
|
"qr-code"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"options": {}
|
"options": {}
|
||||||
|
|||||||
@@ -10289,7 +10289,8 @@
|
|||||||
"openai",
|
"openai",
|
||||||
"zemantic-ai",
|
"zemantic-ai",
|
||||||
"cal-com",
|
"cal-com",
|
||||||
"chat-node"
|
"chat-node",
|
||||||
|
"qr-code"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"options": {}
|
"options": {}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
"@typebot.io/js": "workspace:*",
|
"@typebot.io/js": "workspace:*",
|
||||||
"@typebot.io/nextjs": "workspace:*",
|
"@typebot.io/nextjs": "workspace:*",
|
||||||
"@typebot.io/prisma": "workspace:*",
|
"@typebot.io/prisma": "workspace:*",
|
||||||
"ai": "2.2.24",
|
"ai": "2.2.31",
|
||||||
"bot-engine": "workspace:*",
|
"bot-engine": "workspace:*",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"google-spreadsheet": "4.0.2",
|
"google-spreadsheet": "4.0.2",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"next": "14.0.3",
|
"next": "14.0.3",
|
||||||
"nextjs-cors": "2.1.2",
|
"nextjs-cors": "2.1.2",
|
||||||
"nodemailer": "6.9.3",
|
"nodemailer": "6.9.3",
|
||||||
"openai": "4.19.0",
|
"openai": "4.24.1",
|
||||||
"qs": "6.11.2",
|
"qs": "6.11.2",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"@typebot.io/variables": "workspace:*",
|
"@typebot.io/variables": "workspace:*",
|
||||||
"@udecode/plate-common": "21.1.5",
|
"@udecode/plate-common": "21.1.5",
|
||||||
"@udecode/plate-serializer-md": "24.4.0",
|
"@udecode/plate-serializer-md": "24.4.0",
|
||||||
"ai": "2.2.24",
|
"ai": "2.2.31",
|
||||||
"chrono-node": "2.7.0",
|
"chrono-node": "2.7.0",
|
||||||
"date-fns": "2.30.0",
|
"date-fns": "2.30.0",
|
||||||
"google-auth-library": "8.9.0",
|
"google-auth-library": "8.9.0",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"libphonenumber-js": "1.10.37",
|
"libphonenumber-js": "1.10.37",
|
||||||
"node-html-parser": "6.1.5",
|
"node-html-parser": "6.1.5",
|
||||||
"nodemailer": "6.9.3",
|
"nodemailer": "6.9.3",
|
||||||
"openai": "4.19.0",
|
"openai": "4.24.1",
|
||||||
"qs": "6.11.2",
|
"qs": "6.11.2",
|
||||||
"stripe": "12.13.0"
|
"stripe": "12.13.0"
|
||||||
},
|
},
|
||||||
|
|||||||
172
packages/forge/blocks/openai/actions/askAssistant.tsx
Normal file
172
packages/forge/blocks/openai/actions/askAssistant.tsx
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
import { createAction, option } from '@typebot.io/forge'
|
||||||
|
import { isDefined, isEmpty } from '@typebot.io/lib'
|
||||||
|
import { auth } from '../auth'
|
||||||
|
import { ClientOptions, OpenAI } from 'openai'
|
||||||
|
import { baseOptions } from '../baseOptions'
|
||||||
|
|
||||||
|
export const askAssistant = createAction({
|
||||||
|
auth,
|
||||||
|
baseOptions,
|
||||||
|
name: 'Ask Assistant',
|
||||||
|
options: option.object({
|
||||||
|
assistantId: option.string.layout({
|
||||||
|
label: 'Assistant ID',
|
||||||
|
placeholder: 'Select an assistant',
|
||||||
|
moreInfoTooltip: 'The OpenAI assistant you want to ask question to.',
|
||||||
|
fetcher: 'fetchAssistants',
|
||||||
|
}),
|
||||||
|
threadId: option.string.layout({
|
||||||
|
label: 'Thread ID',
|
||||||
|
moreInfoTooltip:
|
||||||
|
'Used to remember the conversation with the user. If empty, a new thread is created.',
|
||||||
|
}),
|
||||||
|
message: option.string.layout({
|
||||||
|
label: 'Message',
|
||||||
|
inputType: 'textarea',
|
||||||
|
}),
|
||||||
|
responseMapping: option
|
||||||
|
.saveResponseArray(['Message', 'Thread ID'] as const)
|
||||||
|
.layout({
|
||||||
|
accordion: 'Save response',
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
fetchers: [
|
||||||
|
{
|
||||||
|
id: 'fetchAssistants',
|
||||||
|
fetch: async ({ options, credentials }) => {
|
||||||
|
const config = {
|
||||||
|
apiKey: credentials.apiKey,
|
||||||
|
baseURL: options.baseUrl,
|
||||||
|
defaultHeaders: {
|
||||||
|
'api-key': credentials.apiKey,
|
||||||
|
},
|
||||||
|
defaultQuery: options.apiVersion
|
||||||
|
? {
|
||||||
|
'api-version': options.apiVersion,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
} satisfies ClientOptions
|
||||||
|
|
||||||
|
const openai = new OpenAI(config)
|
||||||
|
|
||||||
|
const response = await openai.beta.assistants.list()
|
||||||
|
|
||||||
|
return response.data
|
||||||
|
.map((assistant) =>
|
||||||
|
assistant.name
|
||||||
|
? {
|
||||||
|
label: assistant.name,
|
||||||
|
value: assistant.id,
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
)
|
||||||
|
.filter(isDefined)
|
||||||
|
},
|
||||||
|
dependencies: ['baseUrl', 'apiVersion'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
getSetVariableIds: ({ responseMapping }) =>
|
||||||
|
responseMapping?.map((r) => r.variableId).filter(isDefined) ?? [],
|
||||||
|
run: {
|
||||||
|
server: async ({
|
||||||
|
credentials: { apiKey },
|
||||||
|
options: {
|
||||||
|
baseUrl,
|
||||||
|
apiVersion,
|
||||||
|
assistantId,
|
||||||
|
message,
|
||||||
|
responseMapping,
|
||||||
|
threadId,
|
||||||
|
},
|
||||||
|
variables,
|
||||||
|
logs,
|
||||||
|
}) => {
|
||||||
|
if (isEmpty(assistantId)) {
|
||||||
|
logs.add('Assistant ID is empty')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isEmpty(message)) {
|
||||||
|
logs.add('Message is empty')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const config = {
|
||||||
|
apiKey,
|
||||||
|
baseURL: baseUrl,
|
||||||
|
defaultHeaders: {
|
||||||
|
'api-key': apiKey,
|
||||||
|
},
|
||||||
|
defaultQuery: apiVersion
|
||||||
|
? {
|
||||||
|
'api-version': apiVersion,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
} satisfies ClientOptions
|
||||||
|
|
||||||
|
const openai = new OpenAI(config)
|
||||||
|
|
||||||
|
// Create a thread if needed
|
||||||
|
const currentThreadId = isEmpty(threadId)
|
||||||
|
? (await openai.beta.threads.create({})).id
|
||||||
|
: threadId
|
||||||
|
|
||||||
|
// Add a message to the thread
|
||||||
|
const createdMessage = await openai.beta.threads.messages.create(
|
||||||
|
currentThreadId,
|
||||||
|
{
|
||||||
|
role: 'user',
|
||||||
|
content: message,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const run = await openai.beta.threads.runs.create(currentThreadId, {
|
||||||
|
assistant_id: assistantId,
|
||||||
|
})
|
||||||
|
|
||||||
|
async function waitForRun(run: OpenAI.Beta.Threads.Runs.Run) {
|
||||||
|
// Poll for status change
|
||||||
|
while (run.status === 'queued' || run.status === 'in_progress') {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
|
|
||||||
|
run = await openai.beta.threads.runs.retrieve(currentThreadId, run.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the run status
|
||||||
|
if (
|
||||||
|
run.status === 'cancelled' ||
|
||||||
|
run.status === 'cancelling' ||
|
||||||
|
run.status === 'failed' ||
|
||||||
|
run.status === 'expired'
|
||||||
|
) {
|
||||||
|
throw new Error(run.status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await waitForRun(run)
|
||||||
|
|
||||||
|
const responseMessages = (
|
||||||
|
await openai.beta.threads.messages.list(currentThreadId, {
|
||||||
|
after: createdMessage.id,
|
||||||
|
order: 'asc',
|
||||||
|
})
|
||||||
|
).data
|
||||||
|
|
||||||
|
responseMapping?.forEach((mapping) => {
|
||||||
|
if (!mapping.variableId) return
|
||||||
|
if (!mapping.item || mapping.item === 'Message') {
|
||||||
|
let message = ''
|
||||||
|
const messageContents = responseMessages[0].content
|
||||||
|
for (const content of messageContents) {
|
||||||
|
switch (content.type) {
|
||||||
|
case 'text':
|
||||||
|
message += (message !== '' ? '\n\n' : '') + content.text.value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
variables.set(mapping.variableId, message)
|
||||||
|
}
|
||||||
|
if (mapping.item === 'Thread ID')
|
||||||
|
variables.set(mapping.variableId, currentThreadId)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -20,22 +20,20 @@ export const parseChatCompletionMessages = ({
|
|||||||
const dialogue = variables.get(message.dialogueVariableId) ?? []
|
const dialogue = variables.get(message.dialogueVariableId) ?? []
|
||||||
const dialogueArr = Array.isArray(dialogue) ? dialogue : [dialogue]
|
const dialogueArr = Array.isArray(dialogue) ? dialogue : [dialogue]
|
||||||
|
|
||||||
return dialogueArr.map<OpenAI.Chat.ChatCompletionMessageParam>(
|
return dialogueArr.map((dialogueItem, index) => {
|
||||||
(dialogueItem, index) => {
|
if (index === 0 && message.startsBy === 'assistant')
|
||||||
if (index === 0 && message.startsBy === 'assistant')
|
|
||||||
return {
|
|
||||||
role: 'assistant',
|
|
||||||
content: dialogueItem,
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
role:
|
role: 'assistant',
|
||||||
index % (message.startsBy === 'assistant' ? 1 : 2) === 0
|
|
||||||
? 'user'
|
|
||||||
: 'assistant',
|
|
||||||
content: dialogueItem,
|
content: dialogueItem,
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
role:
|
||||||
|
index % (message.startsBy === 'assistant' ? 1 : 2) === 0
|
||||||
|
? 'user'
|
||||||
|
: 'assistant',
|
||||||
|
content: dialogueItem,
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message.content) return
|
if (!message.content) return
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { createSpeech } from './actions/createSpeech'
|
|||||||
import { createBlock } from '@typebot.io/forge'
|
import { createBlock } from '@typebot.io/forge'
|
||||||
import { auth } from './auth'
|
import { auth } from './auth'
|
||||||
import { baseOptions } from './baseOptions'
|
import { baseOptions } from './baseOptions'
|
||||||
|
import { askAssistant } from './actions/askAssistant'
|
||||||
|
|
||||||
export const openAIBlock = createBlock({
|
export const openAIBlock = createBlock({
|
||||||
id: 'openai' as const,
|
id: 'openai' as const,
|
||||||
@@ -13,5 +14,5 @@ export const openAIBlock = createBlock({
|
|||||||
DarkLogo: OpenAIDarkLogo,
|
DarkLogo: OpenAIDarkLogo,
|
||||||
auth,
|
auth,
|
||||||
options: baseOptions,
|
options: baseOptions,
|
||||||
actions: [createChatCompletion, createSpeech],
|
actions: [createChatCompletion, askAssistant, createSpeech],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
"author": "Baptiste Arnaud",
|
"author": "Baptiste Arnaud",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ai": "2.2.24",
|
"ai": "2.2.31",
|
||||||
"openai": "4.19.0"
|
"openai": "4.24.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typebot.io/forge": "workspace:*",
|
"@typebot.io/forge": "workspace:*",
|
||||||
|
|||||||
36
pnpm-lock.yaml
generated
36
pnpm-lock.yaml
generated
@@ -222,8 +222,8 @@ importers:
|
|||||||
specifier: 0.2.0
|
specifier: 0.2.0
|
||||||
version: 0.2.0
|
version: 0.2.0
|
||||||
openai:
|
openai:
|
||||||
specifier: 4.19.0
|
specifier: 4.24.1
|
||||||
version: 4.19.0
|
version: 4.24.1
|
||||||
papaparse:
|
papaparse:
|
||||||
specifier: 5.4.1
|
specifier: 5.4.1
|
||||||
version: 5.4.1
|
version: 5.4.1
|
||||||
@@ -494,8 +494,8 @@ importers:
|
|||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/prisma
|
version: link:../../packages/prisma
|
||||||
ai:
|
ai:
|
||||||
specifier: 2.2.24
|
specifier: 2.2.31
|
||||||
version: 2.2.24(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.1)(vue@3.3.4)
|
version: 2.2.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.1)(vue@3.3.4)
|
||||||
bot-engine:
|
bot-engine:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/deprecated/bot-engine
|
version: link:../../packages/deprecated/bot-engine
|
||||||
@@ -518,8 +518,8 @@ importers:
|
|||||||
specifier: 6.9.3
|
specifier: 6.9.3
|
||||||
version: 6.9.3
|
version: 6.9.3
|
||||||
openai:
|
openai:
|
||||||
specifier: 4.19.0
|
specifier: 4.24.1
|
||||||
version: 4.19.0
|
version: 4.24.1
|
||||||
qs:
|
qs:
|
||||||
specifier: 6.11.2
|
specifier: 6.11.2
|
||||||
version: 6.11.2
|
version: 6.11.2
|
||||||
@@ -657,8 +657,8 @@ importers:
|
|||||||
specifier: 24.4.0
|
specifier: 24.4.0
|
||||||
version: 24.4.0(react-dom@18.2.0)(react@18.2.0)(scheduler@0.23.0)(slate-history@0.93.0)(slate-hyperscript@0.77.0)(slate-react@0.99.0)(slate@0.94.1)
|
version: 24.4.0(react-dom@18.2.0)(react@18.2.0)(scheduler@0.23.0)(slate-history@0.93.0)(slate-hyperscript@0.77.0)(slate-react@0.99.0)(slate@0.94.1)
|
||||||
ai:
|
ai:
|
||||||
specifier: 2.2.24
|
specifier: 2.2.31
|
||||||
version: 2.2.24(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.1)(vue@3.3.4)
|
version: 2.2.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.1)(vue@3.3.4)
|
||||||
chrono-node:
|
chrono-node:
|
||||||
specifier: 2.7.0
|
specifier: 2.7.0
|
||||||
version: 2.7.0
|
version: 2.7.0
|
||||||
@@ -684,8 +684,8 @@ importers:
|
|||||||
specifier: 6.9.3
|
specifier: 6.9.3
|
||||||
version: 6.9.3
|
version: 6.9.3
|
||||||
openai:
|
openai:
|
||||||
specifier: 4.19.0
|
specifier: 4.24.1
|
||||||
version: 4.19.0
|
version: 4.24.1
|
||||||
qs:
|
qs:
|
||||||
specifier: 6.11.2
|
specifier: 6.11.2
|
||||||
version: 6.11.2
|
version: 6.11.2
|
||||||
@@ -1209,11 +1209,11 @@ importers:
|
|||||||
packages/forge/blocks/openai:
|
packages/forge/blocks/openai:
|
||||||
dependencies:
|
dependencies:
|
||||||
ai:
|
ai:
|
||||||
specifier: 2.2.24
|
specifier: 2.2.31
|
||||||
version: 2.2.24(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.1)(vue@3.3.4)
|
version: 2.2.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.1)(vue@3.3.4)
|
||||||
openai:
|
openai:
|
||||||
specifier: 4.19.0
|
specifier: 4.24.1
|
||||||
version: 4.19.0
|
version: 4.24.1
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@typebot.io/forge':
|
'@typebot.io/forge':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
@@ -9825,8 +9825,8 @@ packages:
|
|||||||
indent-string: 5.0.0
|
indent-string: 5.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/ai@2.2.24(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.1)(vue@3.3.4):
|
/ai@2.2.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.1)(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-j9f89SC08SxN50wKp4ccIGniUMtCsslvOBbYGBCSIvDbMBQaNTZuKW4Id8tmfEeNMV9mwZZ5wRNj6/1Z/pFwYA==}
|
resolution: {integrity: sha512-WQH13RxP+RYo9IE/FX8foNQh9gcKO/dhl9OGy5JL2bHJVBlnugPmH2CYJWaRt+mvjXHaU8txB+jzGo/fbtH2HA==}
|
||||||
engines: {node: '>=14.6'}
|
engines: {node: '>=14.6'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^18.2.0
|
react: ^18.2.0
|
||||||
@@ -17088,8 +17088,8 @@ packages:
|
|||||||
is-docker: 2.2.1
|
is-docker: 2.2.1
|
||||||
is-wsl: 2.2.0
|
is-wsl: 2.2.0
|
||||||
|
|
||||||
/openai@4.19.0:
|
/openai@4.24.1:
|
||||||
resolution: {integrity: sha512-cJbl0noZyAaXVKBTMMq6X5BAvP1pm2rWYDBnZes99NL+Zh5/4NmlAwyuhTZEru5SqGGZIoiYKeMPXy4bm9DI0w==}
|
resolution: {integrity: sha512-ezm/O3eiZMnyBqirUnWm9N6INJU1WhNtz+nK/Zj/2oyKvRz9pgpViDxa5wYOtyGYXPn1sIKBV0I/S4BDhtydqw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 18.11.18
|
'@types/node': 18.11.18
|
||||||
|
|||||||
Reference in New Issue
Block a user