⬆️ (openai) Replace openai-edge with openai and upgrade next
This commit is contained in:
@@ -105,7 +105,7 @@ export const createChatCompletionOpenAI = async (
|
||||
}
|
||||
}
|
||||
|
||||
const { response, logs } = await executeChatCompletionOpenAIRequest({
|
||||
const { chatCompletion, logs } = await executeChatCompletionOpenAIRequest({
|
||||
apiKey,
|
||||
messages,
|
||||
model: options.model,
|
||||
@@ -113,15 +113,15 @@ export const createChatCompletionOpenAI = async (
|
||||
baseUrl: options.baseUrl,
|
||||
apiVersion: options.apiVersion,
|
||||
})
|
||||
if (!response)
|
||||
if (!chatCompletion)
|
||||
return {
|
||||
outgoingEdgeId,
|
||||
logs,
|
||||
}
|
||||
const messageContent = response.choices.at(0)?.message?.content
|
||||
const totalTokens = response.usage?.total_tokens
|
||||
const messageContent = chatCompletion.choices.at(0)?.message?.content
|
||||
const totalTokens = chatCompletion.usage?.total_tokens
|
||||
if (isEmpty(messageContent)) {
|
||||
console.error('OpenAI block returned empty message', response)
|
||||
console.error('OpenAI block returned empty message', chatCompletion.choices)
|
||||
return { outgoingEdgeId, newSessionState }
|
||||
}
|
||||
return resumeChatCompletion(newSessionState, {
|
||||
|
||||
@@ -2,15 +2,12 @@ import { isNotEmpty } from '@typebot.io/lib/utils'
|
||||
import { ChatReply } from '@typebot.io/schemas'
|
||||
import { OpenAIBlock } from '@typebot.io/schemas/features/blocks/integrations/openai'
|
||||
import { HTTPError } from 'got'
|
||||
import {
|
||||
Configuration,
|
||||
OpenAIApi,
|
||||
type CreateChatCompletionRequest,
|
||||
type CreateChatCompletionResponse,
|
||||
ResponseTypes,
|
||||
} from 'openai-edge'
|
||||
import { ClientOptions, OpenAI } from 'openai'
|
||||
|
||||
type Props = Pick<CreateChatCompletionRequest, 'messages' | 'model'> & {
|
||||
type Props = Pick<
|
||||
OpenAI.Chat.ChatCompletionCreateParams,
|
||||
'messages' | 'model'
|
||||
> & {
|
||||
apiKey: string
|
||||
temperature: number | undefined
|
||||
currentLogs?: ChatReply['logs']
|
||||
@@ -27,38 +24,34 @@ export const executeChatCompletionOpenAIRequest = async ({
|
||||
isRetrying,
|
||||
currentLogs = [],
|
||||
}: Props): Promise<{
|
||||
response?: CreateChatCompletionResponse
|
||||
chatCompletion?: OpenAI.Chat.Completions.ChatCompletion
|
||||
logs?: ChatReply['logs']
|
||||
}> => {
|
||||
const logs: ChatReply['logs'] = currentLogs
|
||||
if (messages.length === 0) return { logs }
|
||||
try {
|
||||
const config = new Configuration({
|
||||
const config = {
|
||||
apiKey,
|
||||
basePath: baseUrl,
|
||||
baseOptions: {
|
||||
headers: {
|
||||
'api-key': apiKey,
|
||||
},
|
||||
baseURL: baseUrl,
|
||||
defaultHeaders: {
|
||||
'api-key': apiKey,
|
||||
},
|
||||
defaultQueryParams: isNotEmpty(apiVersion)
|
||||
? new URLSearchParams({
|
||||
defaultQuery: isNotEmpty(apiVersion)
|
||||
? {
|
||||
'api-version': apiVersion,
|
||||
})
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
} satisfies ClientOptions
|
||||
|
||||
const openai = new OpenAIApi(config)
|
||||
const openai = new OpenAI(config)
|
||||
|
||||
const response = await openai.createChatCompletion({
|
||||
const chatCompletion = await openai.chat.completions.create({
|
||||
model,
|
||||
messages,
|
||||
temperature,
|
||||
})
|
||||
|
||||
const completion =
|
||||
(await response.json()) as ResponseTypes['createChatCompletion']
|
||||
return { response: completion, logs }
|
||||
return { chatCompletion, logs }
|
||||
} catch (error) {
|
||||
if (error instanceof HTTPError) {
|
||||
if (
|
||||
|
||||
@@ -7,19 +7,15 @@ import {
|
||||
} from '@typebot.io/schemas/features/blocks/integrations/openai'
|
||||
import { SessionState } from '@typebot.io/schemas/features/chat/sessionState'
|
||||
import { OpenAIStream } from 'ai'
|
||||
import {
|
||||
ChatCompletionRequestMessage,
|
||||
Configuration,
|
||||
OpenAIApi,
|
||||
} from 'openai-edge'
|
||||
import { parseVariableNumber } from '../../../variables/parseVariableNumber'
|
||||
import { ClientOptions, OpenAI } from 'openai'
|
||||
|
||||
export const getChatCompletionStream =
|
||||
(conn: Connection) =>
|
||||
async (
|
||||
state: SessionState,
|
||||
options: ChatCompletionOpenAIOptions,
|
||||
messages: ChatCompletionRequestMessage[]
|
||||
messages: OpenAI.Chat.ChatCompletionMessageParam[]
|
||||
) => {
|
||||
if (!options.credentialsId) return
|
||||
const credentials = (
|
||||
@@ -41,31 +37,27 @@ export const getChatCompletionStream =
|
||||
options.advancedSettings?.temperature
|
||||
)
|
||||
|
||||
const config = new Configuration({
|
||||
const config = {
|
||||
apiKey,
|
||||
basePath: options.baseUrl,
|
||||
baseOptions: {
|
||||
headers: {
|
||||
'api-key': apiKey,
|
||||
},
|
||||
baseURL: options.baseUrl,
|
||||
defaultHeaders: {
|
||||
'api-key': apiKey,
|
||||
},
|
||||
defaultQueryParams: isNotEmpty(options.apiVersion)
|
||||
? new URLSearchParams({
|
||||
defaultQuery: isNotEmpty(options.apiVersion)
|
||||
? {
|
||||
'api-version': options.apiVersion,
|
||||
})
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
} satisfies ClientOptions
|
||||
|
||||
const openai = new OpenAIApi(config)
|
||||
const openai = new OpenAI(config)
|
||||
|
||||
const response = await openai.createChatCompletion({
|
||||
const response = await openai.chat.completions.create({
|
||||
model: options.model,
|
||||
temperature,
|
||||
stream: true,
|
||||
messages,
|
||||
})
|
||||
|
||||
if (!response.ok) return response
|
||||
|
||||
return OpenAIStream(response)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { byId, isNotEmpty } from '@typebot.io/lib'
|
||||
import { Variable, VariableWithValue } from '@typebot.io/schemas'
|
||||
import { ChatCompletionOpenAIOptions } from '@typebot.io/schemas/features/blocks/integrations/openai'
|
||||
import type { ChatCompletionRequestMessage } from 'openai-edge'
|
||||
import type { OpenAI } from 'openai'
|
||||
import { parseVariables } from '../../../variables/parseVariables'
|
||||
import { transformStringVariablesToList } from '../../../variables/transformVariablesToList'
|
||||
|
||||
@@ -11,7 +11,7 @@ export const parseChatCompletionMessages =
|
||||
messages: ChatCompletionOpenAIOptions['messages']
|
||||
): {
|
||||
variablesTransformedToList: VariableWithValue[]
|
||||
messages: ChatCompletionRequestMessage[]
|
||||
messages: OpenAI.Chat.ChatCompletionMessageParam[]
|
||||
} => {
|
||||
const variablesTransformedToList: VariableWithValue[] = []
|
||||
const parsedMessages = messages
|
||||
@@ -47,7 +47,7 @@ export const parseChatCompletionMessages =
|
||||
variable.id === message.content?.assistantMessagesVariableId
|
||||
)?.value ?? []) as string[]
|
||||
|
||||
let allMessages: ChatCompletionRequestMessage[] = []
|
||||
let allMessages: OpenAI.Chat.ChatCompletionMessageParam[] = []
|
||||
|
||||
if (userMessages.length > assistantMessages.length)
|
||||
allMessages = userMessages.flatMap((userMessage, index) => [
|
||||
@@ -56,7 +56,7 @@ export const parseChatCompletionMessages =
|
||||
content: userMessage,
|
||||
},
|
||||
{ role: 'assistant', content: assistantMessages.at(index) ?? '' },
|
||||
]) satisfies ChatCompletionRequestMessage[]
|
||||
]) satisfies OpenAI.Chat.ChatCompletionMessageParam[]
|
||||
else {
|
||||
allMessages = assistantMessages.flatMap(
|
||||
(assistantMessage, index) => [
|
||||
@@ -66,7 +66,7 @@ export const parseChatCompletionMessages =
|
||||
content: userMessages.at(index) ?? '',
|
||||
},
|
||||
]
|
||||
) satisfies ChatCompletionRequestMessage[]
|
||||
) satisfies OpenAI.Chat.ChatCompletionMessageParam[]
|
||||
}
|
||||
|
||||
return allMessages
|
||||
@@ -77,11 +77,11 @@ export const parseChatCompletionMessages =
|
||||
name: message.name
|
||||
? parseVariables(variables)(message.name)
|
||||
: undefined,
|
||||
} satisfies ChatCompletionRequestMessage
|
||||
} satisfies OpenAI.Chat.ChatCompletionMessageParam
|
||||
})
|
||||
.filter(
|
||||
(message) => isNotEmpty(message?.role) && isNotEmpty(message?.content)
|
||||
) as ChatCompletionRequestMessage[]
|
||||
) as OpenAI.Chat.ChatCompletionMessageParam[]
|
||||
|
||||
return {
|
||||
variablesTransformedToList,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"@typebot.io/tsconfig": "workspace:*",
|
||||
"@udecode/plate-common": "^21.1.5",
|
||||
"@udecode/plate-serializer-md": "^24.4.0",
|
||||
"ai": "2.1.32",
|
||||
"ai": "2.2.14",
|
||||
"chrono-node": "2.6.6",
|
||||
"date-fns": "^2.30.0",
|
||||
"google-auth-library": "8.9.0",
|
||||
@@ -27,7 +27,7 @@
|
||||
"libphonenumber-js": "1.10.37",
|
||||
"node-html-parser": "^6.1.5",
|
||||
"nodemailer": "6.9.3",
|
||||
"openai-edge": "1.2.2",
|
||||
"openai": "^4.11.1",
|
||||
"qs": "^6.11.2",
|
||||
"remark-slate": "^1.8.6",
|
||||
"stripe": "12.13.0"
|
||||
|
||||
@@ -63,7 +63,7 @@ export const executeClientSideAction = async ({
|
||||
logs: [
|
||||
{
|
||||
status: 'error',
|
||||
description: 'Failed to stream OpenAI completion',
|
||||
description: 'OpenAI returned an error',
|
||||
details: JSON.stringify(error, null, 2),
|
||||
},
|
||||
],
|
||||
|
||||
2
packages/env/package.json
vendored
2
packages/env/package.json
vendored
@@ -6,7 +6,7 @@
|
||||
"main": "./env.ts",
|
||||
"types": "./env.ts",
|
||||
"dependencies": {
|
||||
"@t3-oss/env-nextjs": "^0.6.0",
|
||||
"@t3-oss/env-nextjs": "^0.7.0",
|
||||
"zod": "3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"@typebot.io/schemas": "workspace:*",
|
||||
"@typebot.io/tsconfig": "workspace:*",
|
||||
"@types/nodemailer": "6.4.8",
|
||||
"next": "13.4.3",
|
||||
"next": "13.5.4",
|
||||
"nodemailer": "6.9.3",
|
||||
"typescript": "5.1.6"
|
||||
},
|
||||
|
||||
@@ -62,7 +62,9 @@ export const isNotDefined = <T>(
|
||||
value: T | undefined | null
|
||||
): value is undefined | null => value === undefined || value === null
|
||||
|
||||
export const isEmpty = (value: string | undefined | null): value is undefined =>
|
||||
export const isEmpty = (
|
||||
value: string | undefined | null
|
||||
): value is undefined | null =>
|
||||
value === undefined || value === null || value === ''
|
||||
|
||||
export const isNotEmpty = (value: string | undefined | null): value is string =>
|
||||
|
||||
Reference in New Issue
Block a user