2
0

🐛 (openai) Fix ask assistant not correctly referencing uploaded f… (#1469)

…iles

Closes #1468, closes #1467, closes #1211
This commit is contained in:
Baptiste Arnaud
2024-04-24 16:11:06 +02:00
committed by GitHub
parent a45e8ec8a8
commit dc1929e15b
57 changed files with 1576 additions and 448 deletions

View File

@ -128,7 +128,7 @@
"eslint-config-custom": "workspace:*",
"next-runtime-env": "1.6.2",
"superjson": "1.12.4",
"typescript": "5.3.2",
"typescript": "5.4.5",
"zod": "3.22.4"
}
}

View File

@ -22,9 +22,9 @@
"@typebot.io/prisma": "workspace:*",
"@typebot.io/schemas": "workspace:*",
"@typebot.io/variables": "workspace:*",
"ai": "3.0.12",
"ai": "3.0.31",
"hono": "4.0.5",
"openai": "4.28.4",
"openai": "4.38.3",
"prom-client": "15.1.0"
},
"devDependencies": {

View File

@ -19149,7 +19149,7 @@
"assistantId": {
"type": "string"
},
"threadId": {
"threadVariableId": {
"type": "string"
},
"message": {
@ -19186,6 +19186,9 @@
}
}
}
},
"threadId": {
"type": "string"
}
},
"required": [

View File

@ -9977,7 +9977,7 @@
"assistantId": {
"type": "string"
},
"threadId": {
"threadVariableId": {
"type": "string"
},
"message": {
@ -10014,6 +10014,9 @@
}
}
}
},
"threadId": {
"type": "string"
}
},
"required": [
@ -12480,18 +12483,10 @@
}
}
}
},
"runtime": {
"type": "string",
"enum": [
"edge",
"nodejs"
]
}
},
"required": [
"messages",
"runtime"
"messages"
]
},
"lastBubbleBlockId": {
@ -12768,13 +12763,6 @@
true
]
},
"runtime": {
"type": "string",
"enum": [
"edge",
"nodejs"
]
},
"lastBubbleBlockId": {
"type": "string"
},
@ -12784,8 +12772,7 @@
},
"required": [
"type",
"stream",
"runtime"
"stream"
],
"title": "Exec stream"
},

View File

@ -48,6 +48,6 @@
"postcss": "8.4.26",
"prettier": "3.0.0",
"tailwindcss": "3.3.3",
"typescript": "5.3.2"
"typescript": "5.4.5"
}
}

View File

@ -21,7 +21,7 @@
"@typebot.io/js": "workspace:*",
"@typebot.io/nextjs": "workspace:*",
"@typebot.io/prisma": "workspace:*",
"ai": "3.0.12",
"ai": "3.0.31",
"bot-engine": "workspace:*",
"cors": "2.8.5",
"google-spreadsheet": "4.1.1",
@ -30,7 +30,7 @@
"next": "14.1.0",
"nextjs-cors": "2.1.2",
"nodemailer": "6.9.8",
"openai": "4.28.4",
"openai": "4.38.3",
"qs": "6.11.2",
"react": "18.2.0",
"react-dom": "18.2.0",
@ -62,7 +62,7 @@
"next-runtime-env": "1.6.2",
"papaparse": "5.4.1",
"superjson": "1.12.4",
"typescript": "5.3.2",
"typescript": "5.4.5",
"zod": "3.22.4",
"@typebot.io/playwright": "workspace:*",
"@typebot.io/results": "workspace:*"

View File

@ -7,7 +7,7 @@ import { NextResponse } from 'next/dist/server/web/spec-extension/response'
import { getBlockById } from '@typebot.io/schemas/helpers'
import { forgedBlocks } from '@typebot.io/forge-repository/definitions'
import { decryptV2 } from '@typebot.io/lib/api/encryption/decryptV2'
import { ReadOnlyVariableStore } from '@typebot.io/forge'
import { VariableStore } from '@typebot.io/forge'
import {
ParseVariablesOptions,
parseVariables,
@ -38,6 +38,7 @@ export async function OPTIONS() {
})
}
// Deprecated in favor of `/api/v1/sessions/:sessionId/streamMessage`.
export async function POST(req: Request) {
const { sessionId, messages } = (await req.json()) as {
messages: OpenAI.Chat.ChatCompletionMessage[] | undefined
@ -140,7 +141,7 @@ export async function POST(req: Request) {
credentials.data,
credentials.iv
)
const variables: ReadOnlyVariableStore = {
const variables: VariableStore = {
list: () => state.typebotsQueue[0].typebot.variables,
get: (id: string) => {
const variable = state.typebotsQueue[0].typebot.variables.find(
@ -150,6 +151,8 @@ export async function POST(req: Request) {
},
parse: (text: string, params?: ParseVariablesOptions) =>
parseVariables(state.typebotsQueue[0].typebot.variables, params)(text),
// eslint-disable-next-line @typescript-eslint/no-unused-vars
set: (_1: string, _2: unknown) => {},
}
const stream = await action.run.stream.run({
credentials: decryptedCredentials,

View File

@ -26,11 +26,6 @@ export async function POST(
req: Request,
{ params }: { params: { sessionId: string } }
) {
if (process.env.VERCEL_ENV)
return NextResponse.json(
{ message: "Can't get streaming if hosted on Vercel" },
{ status: 400, headers: responseHeaders }
)
const messages =
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const { stream, status, message } = await getMessageStream({
@ -39,7 +34,22 @@ export async function POST(
})
if (!stream)
return NextResponse.json({ message }, { status, headers: responseHeaders })
return new StreamingTextResponse(stream, {
return new StreamingTextResponse(
stream.pipeThrough(createStreamDataTransformer()),
{
headers: responseHeaders,
}
)
}
const createStreamDataTransformer = () => {
const encoder = new TextEncoder()
const decoder = new TextDecoder()
return new TransformStream({
transform: async (chunk, controller) => {
const decodedChunk = decoder.decode(chunk)
if (decodedChunk[0] !== '0') return
controller.enqueue(encoder.encode(JSON.parse(decodedChunk.slice(2))))
},
})
}

View File

@ -0,0 +1,40 @@
import { getMessageStream } from '@typebot.io/bot-engine/apiHandlers/getMessageStream'
import { StreamingTextResponse } from 'ai'
import { NextResponse } from 'next/server'
export const dynamic = 'force-dynamic'
const responseHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Expose-Headers': 'Content-Length, X-JSON',
'Access-Control-Allow-Headers': '*',
}
export async function OPTIONS() {
return new Response('ok', {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Expose-Headers': 'Content-Length, X-JSON',
'Access-Control-Allow-Headers': '*',
},
})
}
export async function POST(
req: Request,
{ params }: { params: { sessionId: string } }
) {
const messages =
typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const { stream, status, message } = await getMessageStream({
sessionId: params.sessionId,
messages,
})
if (!stream)
return NextResponse.json({ message }, { status, headers: responseHeaders })
return new StreamingTextResponse(stream, {
headers: responseHeaders,
})
}

View File

@ -3,7 +3,7 @@ import { ChatCompletionOpenAIOptions } from '@typebot.io/schemas/features/blocks
import { OpenAI } from 'openai'
import { decryptV2 } from '@typebot.io/lib/api/encryption/decryptV2'
import { forgedBlocks } from '@typebot.io/forge-repository/definitions'
import { ReadOnlyVariableStore } from '@typebot.io/forge'
import { VariableStore } from '@typebot.io/forge'
import {
ParseVariablesOptions,
parseVariables,
@ -13,6 +13,9 @@ import { getCredentials } from '../queries/getCredentials'
import { getSession } from '../queries/getSession'
import { getBlockById } from '@typebot.io/schemas/helpers'
import { isForgedBlockType } from '@typebot.io/schemas/features/blocks/forged/helpers'
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
import { updateSession } from '../queries/updateSession'
import { deepParseVariables } from '@typebot.io/variables/deepParseVariables'
type Props = {
sessionId: string
@ -92,7 +95,8 @@ export const getMessageStream = async ({ sessionId, messages }: Props) => {
credentials.data,
credentials.iv
)
const variables: ReadOnlyVariableStore = {
const variables: VariableStore = {
list: () => session.state.typebotsQueue[0].typebot.variables,
get: (id: string) => {
const variable = session.state.typebotsQueue[0].typebot.variables.find(
@ -105,10 +109,25 @@ export const getMessageStream = async ({ sessionId, messages }: Props) => {
session.state.typebotsQueue[0].typebot.variables,
params
)(text),
set: async (id: string, value: unknown) => {
const variable = session.state.typebotsQueue[0].typebot.variables.find(
(variable) => variable.id === id
)
if (!variable) return
await updateSession({
id: session.id,
state: updateVariablesInSession(session.state)([
{ ...variable, value },
]),
isReplying: undefined,
})
},
}
const stream = await action.run.stream.run({
credentials: decryptedCredentials,
options: block.options,
options: deepParseVariables(
session.state.typebotsQueue[0].typebot.variables
)(block.options),
variables,
})
if (!stream) return { status: 500, message: 'Could not create stream' }

View File

@ -89,9 +89,7 @@ export const createChatCompletionOpenAI = async (
isNextBubbleMessageWithAssistantMessage(typebot)(
blockId,
assistantMessageVariableName
) &&
(!process.env.VERCEL_ENV ||
(isPlaneteScale() && credentials && isCredentialsV2(credentials)))
)
) {
return {
clientSideActions: [
@ -102,7 +100,6 @@ export const createChatCompletionOpenAI = async (
content?: string
role: (typeof chatCompletionMessageRoles)[number]
}[],
runtime: process.env.VERCEL_ENV ? 'edge' : 'nodejs',
},
expectsDedicatedReply: true,
},

View File

@ -58,9 +58,7 @@ export const executeForgedBlock = async (
action.run.stream.getStreamVariableId(block.options)
) &&
state.isStreamEnabled &&
!state.whatsApp &&
(!process.env.VERCEL_ENV ||
(isPlaneteScale() && credentials && isCredentialsV2(credentials)))
!state.whatsApp
) {
return {
outgoingEdgeId: block.outgoingEdgeId,
@ -69,7 +67,6 @@ export const executeForgedBlock = async (
type: 'stream',
expectsDedicatedReply: true,
stream: true,
runtime: process.env.VERCEL_ENV ? 'edge' : 'nodejs',
},
],
}

View File

@ -19,7 +19,7 @@
"@typebot.io/tsconfig": "workspace:*",
"@typebot.io/variables": "workspace:*",
"@udecode/plate-common": "30.4.5",
"ai": "3.0.12",
"ai": "3.0.31",
"chrono-node": "2.7.5",
"date-fns": "2.30.0",
"date-fns-tz": "2.0.0",
@ -29,7 +29,7 @@
"libphonenumber-js": "1.10.37",
"node-html-parser": "6.1.5",
"nodemailer": "6.9.8",
"openai": "4.28.4",
"openai": "4.38.3",
"qs": "6.11.2",
"stripe": "12.13.0"
},

View File

@ -5,7 +5,7 @@ import { SessionState } from '@typebot.io/schemas'
type Props = {
id: string
state: SessionState
isReplying: boolean
isReplying: boolean | undefined
}
export const updateSession = ({

View File

@ -6,7 +6,7 @@
"main": "dist/index.js",
"module": "dist/index.mjs",
"scripts": {
"build": "pnpm tsc --noEmit && tsup",
"build": "tsup",
"dev": "tsup --watch"
},
"dependencies": {
@ -40,7 +40,7 @@
"@typebot.io/tsconfig": "workspace:*",
"tsup": "6.5.0",
"typebot-js": "workspace:*",
"typescript": "5.3.2",
"typescript": "5.4.5",
"@typebot.io/lib": "workspace:*",
"@typebot.io/env": "workspace:*"
},

View File

@ -18,7 +18,7 @@
"jest-environment-jsdom": "29.4.1",
"prettier": "2.8.3",
"ts-jest": "29.0.5",
"typescript": "5.3.2",
"typescript": "5.4.5",
"@typebot.io/tsconfig": "workspace:*"
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/js",
"version": "0.2.77",
"version": "0.2.78",
"description": "Javascript library to display typebots on your website",
"type": "module",
"main": "dist/index.js",
@ -46,6 +46,6 @@
"rollup-plugin-postcss": "4.0.2",
"rollup-plugin-typescript-paths": "1.4.0",
"tailwindcss": "3.3.3",
"typescript": "5.3.2"
"typescript": "5.4.5"
}
}

View File

@ -165,8 +165,8 @@ export const ChatChunk = (props: Props) => {
class="flex flex-col flex-1 gap-2"
style={{
'max-width':
props.theme.chat?.hostAvatar?.isEnabled ??
defaultHostAvatarIsEnabled
props.theme.chat?.guestAvatar?.isEnabled ??
defaultGuestAvatarIsEnabled
? isMobile()
? 'calc(100% - 32px - 32px)'
: 'calc(100% - 48px - 48px)'

View File

@ -27,7 +27,7 @@ export const StreamingBubble = (props: Props) => {
.map((block, index) => {
if (index % 2 === 0) {
return block.split('\n\n').map((line) =>
domPurify.sanitize(marked.parse(line), {
domPurify.sanitize(marked.parse(line.replace(/【.+】/g, '')), {
ADD_ATTR: ['target'],
})
)

View File

@ -1,4 +1,5 @@
import { ClientSideActionContext } from '@/types'
import { readDataStream } from '@/utils/ai/readDataStream'
import { guessApiHost } from '@/utils/guessApiHost'
import { isNotEmpty } from '@typebot.io/lib/utils'
import { createUniqueId } from 'solid-js'
@ -7,22 +8,16 @@ let abortController: AbortController | null = null
const secondsToWaitBeforeRetries = 3
const maxRetryAttempts = 3
const edgeRuntimePath = '/api/integrations/openai/streamer'
const nodejsRuntimePath = (sessionId: string) =>
`/api/v1/sessions/${sessionId}/streamMessage`
export const streamChat =
(context: ClientSideActionContext & { retryAttempt?: number }) =>
async ({
messages,
runtime,
onMessageStream,
}: {
messages?: {
content?: string | undefined
role?: 'system' | 'user' | 'assistant' | undefined
}[]
runtime: 'edge' | 'nodejs'
onMessageStream?: (props: { id: string; message: string }) => void
}): Promise<{ message?: string; error?: object }> => {
try {
@ -31,12 +26,8 @@ export const streamChat =
const apiHost = context.apiHost
const res = await fetch(
isNotEmpty(apiHost)
? apiHost
: guessApiHost() +
(runtime === 'edge'
? edgeRuntimePath
: nodejsRuntimePath(context.sessionId)),
(isNotEmpty(apiHost) ? apiHost : guessApiHost()) +
`/api/v2/sessions/${context.sessionId}/streamMessage`,
{
method: 'POST',
headers: {
@ -44,7 +35,6 @@ export const streamChat =
},
body: JSON.stringify({
messages,
sessionId: runtime === 'edge' ? context.sessionId : undefined,
}),
signal: abortController.signal,
}
@ -61,7 +51,7 @@ export const streamChat =
return streamChat({
...context,
retryAttempt: (context.retryAttempt ?? 0) + 1,
})({ messages, onMessageStream, runtime })
})({ messages, onMessageStream })
}
return {
error: (await res.json()) || 'Failed to fetch the chat response.',
@ -75,22 +65,15 @@ export const streamChat =
let message = ''
const reader = res.body.getReader()
const decoder = new TextDecoder()
const id = createUniqueId()
// eslint-disable-next-line no-constant-condition
while (true) {
const { done, value } = await reader.read()
if (done) {
break
}
const chunk = decoder.decode(value)
message += chunk
for await (const { type, value } of readDataStream(reader, {
isAborted: () => abortController === null,
})) {
if (type === 'text') {
message += value
if (onMessageStream) onMessageStream({ id, message })
if (abortController === null) {
reader.cancel()
break
}
}

View File

@ -0,0 +1,80 @@
import { StreamPartType, parseStreamPart } from './streamParts'
const NEWLINE = '\n'.charCodeAt(0)
// concatenates all the chunks into a single Uint8Array
function concatChunks(chunks: Uint8Array[], totalLength: number) {
const concatenatedChunks = new Uint8Array(totalLength)
let offset = 0
for (const chunk of chunks) {
concatenatedChunks.set(chunk, offset)
offset += chunk.length
}
chunks.length = 0
return concatenatedChunks
}
/**
Converts a ReadableStreamDefaultReader into an async generator that yields
StreamPart objects.
@param reader
Reader for the stream to read from.
@param isAborted
Optional function that returns true if the request has been aborted.
If the function returns true, the generator will stop reading the stream.
If the function is not provided, the generator will not stop reading the stream.
*/
export async function* readDataStream(
reader: ReadableStreamDefaultReader<Uint8Array>,
{
isAborted,
}: {
isAborted?: () => boolean
} = {}
): AsyncGenerator<StreamPartType> {
// implementation note: this slightly more complex algorithm is required
// to pass the tests in the edge environment.
const decoder = new TextDecoder()
const chunks: Uint8Array[] = []
let totalLength = 0
while (true) {
const { value } = await reader.read()
if (value) {
chunks.push(value)
totalLength += value.length
if (value[value.length - 1] !== NEWLINE) {
// if the last character is not a newline, we have not read the whole JSON value
continue
}
}
if (chunks.length === 0) {
break // we have reached the end of the stream
}
const concatenatedChunks = concatChunks(chunks, totalLength)
totalLength = 0
const streamParts = decoder
.decode(concatenatedChunks, { stream: true })
.split('\n')
.filter((line) => line !== '') // splitting leaves an empty string at the end
.map(parseStreamPart)
for (const streamPart of streamParts) {
yield streamPart
}
// The request has been aborted, stop reading the stream.
if (isAborted?.()) {
reader.cancel()
break
}
}
}

View File

@ -0,0 +1,377 @@
import {
AssistantMessage,
DataMessage,
FunctionCall,
JSONValue,
ToolCall,
} from './types'
type StreamString =
`${(typeof StreamStringPrefixes)[keyof typeof StreamStringPrefixes]}:${string}\n`
export interface StreamPart<CODE extends string, NAME extends string, TYPE> {
code: CODE
name: NAME
parse: (value: JSONValue) => { type: NAME; value: TYPE }
}
const textStreamPart: StreamPart<'0', 'text', string> = {
code: '0',
name: 'text',
parse: (value: JSONValue) => {
if (typeof value !== 'string') {
throw new Error('"text" parts expect a string value.')
}
return { type: 'text', value }
},
}
const functionCallStreamPart: StreamPart<
'1',
'function_call',
{ function_call: FunctionCall }
> = {
code: '1',
name: 'function_call',
parse: (value: JSONValue) => {
if (
value == null ||
typeof value !== 'object' ||
!('function_call' in value) ||
typeof value.function_call !== 'object' ||
value.function_call == null ||
!('name' in value.function_call) ||
!('arguments' in value.function_call) ||
typeof value.function_call.name !== 'string' ||
typeof value.function_call.arguments !== 'string'
) {
throw new Error(
'"function_call" parts expect an object with a "function_call" property.'
)
}
return {
type: 'function_call',
value: value as unknown as { function_call: FunctionCall },
}
},
}
const dataStreamPart: StreamPart<'2', 'data', Array<JSONValue>> = {
code: '2',
name: 'data',
parse: (value: JSONValue) => {
if (!Array.isArray(value)) {
throw new Error('"data" parts expect an array value.')
}
return { type: 'data', value }
},
}
const errorStreamPart: StreamPart<'3', 'error', string> = {
code: '3',
name: 'error',
parse: (value: JSONValue) => {
if (typeof value !== 'string') {
throw new Error('"error" parts expect a string value.')
}
return { type: 'error', value }
},
}
const assistantMessageStreamPart: StreamPart<
'4',
'assistant_message',
AssistantMessage
> = {
code: '4',
name: 'assistant_message',
parse: (value: JSONValue) => {
if (
value == null ||
typeof value !== 'object' ||
!('id' in value) ||
!('role' in value) ||
!('content' in value) ||
typeof value.id !== 'string' ||
typeof value.role !== 'string' ||
value.role !== 'assistant' ||
!Array.isArray(value.content) ||
!value.content.every(
(item) =>
item != null &&
typeof item === 'object' &&
'type' in item &&
item.type === 'text' &&
'text' in item &&
item.text != null &&
typeof item.text === 'object' &&
'value' in item.text &&
typeof item.text.value === 'string'
)
) {
throw new Error(
'"assistant_message" parts expect an object with an "id", "role", and "content" property.'
)
}
return {
type: 'assistant_message',
value: value as AssistantMessage,
}
},
}
const assistantControlDataStreamPart: StreamPart<
'5',
'assistant_control_data',
{
threadId: string
messageId: string
}
> = {
code: '5',
name: 'assistant_control_data',
parse: (value: JSONValue) => {
if (
value == null ||
typeof value !== 'object' ||
!('threadId' in value) ||
!('messageId' in value) ||
typeof value.threadId !== 'string' ||
typeof value.messageId !== 'string'
) {
throw new Error(
'"assistant_control_data" parts expect an object with a "threadId" and "messageId" property.'
)
}
return {
type: 'assistant_control_data',
value: {
threadId: value.threadId,
messageId: value.messageId,
},
}
},
}
const dataMessageStreamPart: StreamPart<'6', 'data_message', DataMessage> = {
code: '6',
name: 'data_message',
parse: (value: JSONValue) => {
if (
value == null ||
typeof value !== 'object' ||
!('role' in value) ||
!('data' in value) ||
typeof value.role !== 'string' ||
value.role !== 'data'
) {
throw new Error(
'"data_message" parts expect an object with a "role" and "data" property.'
)
}
return {
type: 'data_message',
value: value as DataMessage,
}
},
}
const toolCallStreamPart: StreamPart<
'7',
'tool_calls',
{ tool_calls: ToolCall[] }
> = {
code: '7',
name: 'tool_calls',
parse: (value: JSONValue) => {
if (
value == null ||
typeof value !== 'object' ||
!('tool_calls' in value) ||
typeof value.tool_calls !== 'object' ||
value.tool_calls == null ||
!Array.isArray(value.tool_calls) ||
value.tool_calls.some(
(tc) =>
tc == null ||
typeof tc !== 'object' ||
!('id' in tc) ||
typeof tc.id !== 'string' ||
!('type' in tc) ||
typeof tc.type !== 'string' ||
!('function' in tc) ||
tc.function == null ||
typeof tc.function !== 'object' ||
!('arguments' in tc.function) ||
typeof tc.function.name !== 'string' ||
typeof tc.function.arguments !== 'string'
)
) {
throw new Error(
'"tool_calls" parts expect an object with a ToolCallPayload.'
)
}
return {
type: 'tool_calls',
value: value as unknown as { tool_calls: ToolCall[] },
}
},
}
const messageAnnotationsStreamPart: StreamPart<
'8',
'message_annotations',
Array<JSONValue>
> = {
code: '8',
name: 'message_annotations',
parse: (value: JSONValue) => {
if (!Array.isArray(value)) {
throw new Error('"message_annotations" parts expect an array value.')
}
return { type: 'message_annotations', value }
},
}
const streamParts = [
textStreamPart,
functionCallStreamPart,
dataStreamPart,
errorStreamPart,
assistantMessageStreamPart,
assistantControlDataStreamPart,
dataMessageStreamPart,
toolCallStreamPart,
messageAnnotationsStreamPart,
] as const
// union type of all stream parts
type StreamParts =
| typeof textStreamPart
| typeof functionCallStreamPart
| typeof dataStreamPart
| typeof errorStreamPart
| typeof assistantMessageStreamPart
| typeof assistantControlDataStreamPart
| typeof dataMessageStreamPart
| typeof toolCallStreamPart
| typeof messageAnnotationsStreamPart
/**
* Maps the type of a stream part to its value type.
*/
type StreamPartValueType = {
[P in StreamParts as P['name']]: ReturnType<P['parse']>['value']
}
export type StreamPartType =
| ReturnType<typeof textStreamPart.parse>
| ReturnType<typeof functionCallStreamPart.parse>
| ReturnType<typeof dataStreamPart.parse>
| ReturnType<typeof errorStreamPart.parse>
| ReturnType<typeof assistantMessageStreamPart.parse>
| ReturnType<typeof assistantControlDataStreamPart.parse>
| ReturnType<typeof dataMessageStreamPart.parse>
| ReturnType<typeof toolCallStreamPart.parse>
| ReturnType<typeof messageAnnotationsStreamPart.parse>
export const streamPartsByCode = {
[textStreamPart.code]: textStreamPart,
[functionCallStreamPart.code]: functionCallStreamPart,
[dataStreamPart.code]: dataStreamPart,
[errorStreamPart.code]: errorStreamPart,
[assistantMessageStreamPart.code]: assistantMessageStreamPart,
[assistantControlDataStreamPart.code]: assistantControlDataStreamPart,
[dataMessageStreamPart.code]: dataMessageStreamPart,
[toolCallStreamPart.code]: toolCallStreamPart,
[messageAnnotationsStreamPart.code]: messageAnnotationsStreamPart,
} as const
/**
* The map of prefixes for data in the stream
*
* - 0: Text from the LLM response
* - 1: (OpenAI) function_call responses
* - 2: custom JSON added by the user using `Data`
* - 6: (OpenAI) tool_call responses
*
* Example:
* ```
* 0:Vercel
* 0:'s
* 0: AI
* 0: AI
* 0: SDK
* 0: is great
* 0:!
* 2: { "someJson": "value" }
* 1: {"function_call": {"name": "get_current_weather", "arguments": "{\\n\\"location\\": \\"Charlottesville, Virginia\\",\\n\\"format\\": \\"celsius\\"\\n}"}}
* 6: {"tool_call": {"id": "tool_0", "type": "function", "function": {"name": "get_current_weather", "arguments": "{\\n\\"location\\": \\"Charlottesville, Virginia\\",\\n\\"format\\": \\"celsius\\"\\n}"}}}
*```
*/
export const StreamStringPrefixes = {
[textStreamPart.name]: textStreamPart.code,
[functionCallStreamPart.name]: functionCallStreamPart.code,
[dataStreamPart.name]: dataStreamPart.code,
[errorStreamPart.name]: errorStreamPart.code,
[assistantMessageStreamPart.name]: assistantMessageStreamPart.code,
[assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,
[dataMessageStreamPart.name]: dataMessageStreamPart.code,
[toolCallStreamPart.name]: toolCallStreamPart.code,
[messageAnnotationsStreamPart.name]: messageAnnotationsStreamPart.code,
} as const
export const validCodes = streamParts.map((part) => part.code)
/**
Parses a stream part from a string.
@param line The string to parse.
@returns The parsed stream part.
@throws An error if the string cannot be parsed.
*/
export const parseStreamPart = (line: string): StreamPartType => {
const firstSeparatorIndex = line.indexOf(':')
if (firstSeparatorIndex === -1) {
throw new Error('Failed to parse stream string. No separator found.')
}
const prefix = line.slice(0, firstSeparatorIndex)
if (!validCodes.includes(prefix as keyof typeof streamPartsByCode)) {
throw new Error(`Failed to parse stream string. Invalid code ${prefix}.`)
}
const code = prefix as keyof typeof streamPartsByCode
const textValue = line.slice(firstSeparatorIndex + 1)
const jsonValue: JSONValue = JSON.parse(textValue)
return streamPartsByCode[code].parse(jsonValue)
}
/**
Prepends a string with a prefix from the `StreamChunkPrefixes`, JSON-ifies it,
and appends a new line.
It ensures type-safety for the part type and value.
*/
export function formatStreamPart<T extends keyof StreamPartValueType>(
type: T,
value: StreamPartValueType[T]
): StreamString {
const streamPart = streamParts.find((part) => part.name === type)
if (!streamPart) {
throw new Error(`Invalid stream part type: ${type}`)
}
return `${streamPart.code}:${JSON.stringify(value)}\n`
}

View File

@ -0,0 +1,355 @@
/* eslint-disable @typescript-eslint/ban-types */
// https://github.com/openai/openai-node/blob/07b3504e1c40fd929f4aae1651b83afc19e3baf8/src/resources/chat/completions.ts#L146-L159
export interface FunctionCall {
/**
* The arguments to call the function with, as generated by the model in JSON
* format. Note that the model does not always generate valid JSON, and may
* hallucinate parameters not defined by your function schema. Validate the
* arguments in your code before calling your function.
*/
arguments?: string
/**
* The name of the function to call.
*/
name?: string
}
/**
* The tool calls generated by the model, such as function calls.
*/
export interface ToolCall {
// The ID of the tool call.
id: string
// The type of the tool. Currently, only `function` is supported.
type: string
// The function that the model called.
function: {
// The name of the function.
name: string
// The arguments to call the function with, as generated by the model in JSON
arguments: string
}
}
/**
* Controls which (if any) function is called by the model.
* - none means the model will not call a function and instead generates a message.
* - auto means the model can pick between generating a message or calling a function.
* - Specifying a particular function via {"type: "function", "function": {"name": "my_function"}} forces the model to call that function.
* none is the default when no functions are present. auto is the default if functions are present.
*/
export type ToolChoice =
| 'none'
| 'auto'
| { type: 'function'; function: { name: string } }
/**
* A list of tools the model may call. Currently, only functions are supported as a tool.
* Use this to provide a list of functions the model may generate JSON inputs for.
*/
export interface Tool {
type: 'function'
function: Function
}
export interface Function {
/**
* The name of the function to be called. Must be a-z, A-Z, 0-9, or contain
* underscores and dashes, with a maximum length of 64.
*/
name: string
/**
* The parameters the functions accepts, described as a JSON Schema object. See the
* [guide](/docs/guides/gpt/function-calling) for examples, and the
* [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for
* documentation about the format.
*
* To describe a function that accepts no parameters, provide the value
* `{"type": "object", "properties": {}}`.
*/
parameters: Record<string, unknown>
/**
* A description of what the function does, used by the model to choose when and
* how to call the function.
*/
description?: string
}
export type IdGenerator = () => string
/**
* Shared types between the API and UI packages.
*/
export interface Message {
id: string
tool_call_id?: string
createdAt?: Date
content: string
ui?: string | JSX.Element | JSX.Element[] | null | undefined
role: 'system' | 'user' | 'assistant' | 'function' | 'data' | 'tool'
/**
* If the message has a role of `function`, the `name` field is the name of the function.
* Otherwise, the name field should not be set.
*/
name?: string
/**
* If the assistant role makes a function call, the `function_call` field
* contains the function call name and arguments. Otherwise, the field should
* not be set. (Deprecated and replaced by tool_calls.)
*/
function_call?: string | FunctionCall
data?: JSONValue
/**
* If the assistant role makes a tool call, the `tool_calls` field contains
* the tool call name and arguments. Otherwise, the field should not be set.
*/
tool_calls?: string | ToolCall[]
/**
* Additional message-specific information added on the server via StreamData
*/
annotations?: JSONValue[] | undefined
}
export type CreateMessage = Omit<Message, 'id'> & {
id?: Message['id']
}
export type ChatRequest = {
messages: Message[]
options?: RequestOptions
// @deprecated
functions?: Array<Function>
// @deprecated
function_call?: FunctionCall
data?: Record<string, string>
tools?: Array<Tool>
tool_choice?: ToolChoice
}
export type FunctionCallHandler = (
chatMessages: Message[],
functionCall: FunctionCall
) => Promise<ChatRequest | void>
export type ToolCallHandler = (
chatMessages: Message[],
toolCalls: ToolCall[]
) => Promise<ChatRequest | void>
export type RequestOptions = {
headers?: Record<string, string> | Headers
body?: object
}
export type ChatRequestOptions = {
options?: RequestOptions
functions?: Array<Function>
function_call?: FunctionCall
tools?: Array<Tool>
tool_choice?: ToolChoice
data?: Record<string, string>
}
export type UseChatOptions = {
/**
* The API endpoint that accepts a `{ messages: Message[] }` object and returns
* a stream of tokens of the AI chat response. Defaults to `/api/chat`.
*/
api?: string
/**
* A unique identifier for the chat. If not provided, a random one will be
* generated. When provided, the `useChat` hook with the same `id` will
* have shared states across components.
*/
id?: string
/**
* Initial messages of the chat. Useful to load an existing chat history.
*/
initialMessages?: Message[]
/**
* Initial input of the chat.
*/
initialInput?: string
/**
* Callback function to be called when a function call is received.
* If the function returns a `ChatRequest` object, the request will be sent
* automatically to the API and will be used to update the chat.
*/
experimental_onFunctionCall?: FunctionCallHandler
/**
* Callback function to be called when a tool call is received.
* If the function returns a `ChatRequest` object, the request will be sent
* automatically to the API and will be used to update the chat.
*/
experimental_onToolCall?: ToolCallHandler
/**
* Callback function to be called when the API response is received.
*/
onResponse?: (response: Response) => void | Promise<void>
/**
* Callback function to be called when the chat is finished streaming.
*/
onFinish?: (message: Message) => void
/**
* Callback function to be called when an error is encountered.
*/
onError?: (error: Error) => void
/**
* A way to provide a function that is going to be used for ids for messages.
* If not provided nanoid is used by default.
*/
generateId?: IdGenerator
/**
* The credentials mode to be used for the fetch request.
* Possible values are: 'omit', 'same-origin', 'include'.
* Defaults to 'same-origin'.
*/
credentials?: RequestCredentials
/**
* HTTP headers to be sent with the API request.
*/
headers?: Record<string, string> | Headers
/**
* Extra body object to be sent with the API request.
* @example
* Send a `sessionId` to the API along with the messages.
* ```js
* useChat({
* body: {
* sessionId: '123',
* }
* })
* ```
*/
body?: object
/**
* Whether to send extra message fields such as `message.id` and `message.createdAt` to the API.
* Defaults to `false`. When set to `true`, the API endpoint might need to
* handle the extra fields before forwarding the request to the AI service.
*/
sendExtraMessageFields?: boolean
/** Stream mode (default to "stream-data") */
streamMode?: 'stream-data' | 'text'
}
export type UseCompletionOptions = {
/**
* The API endpoint that accepts a `{ prompt: string }` object and returns
* a stream of tokens of the AI completion response. Defaults to `/api/completion`.
*/
api?: string
/**
* An unique identifier for the chat. If not provided, a random one will be
* generated. When provided, the `useChat` hook with the same `id` will
* have shared states across components.
*/
id?: string
/**
* Initial prompt input of the completion.
*/
initialInput?: string
/**
* Initial completion result. Useful to load an existing history.
*/
initialCompletion?: string
/**
* Callback function to be called when the API response is received.
*/
onResponse?: (response: Response) => void | Promise<void>
/**
* Callback function to be called when the completion is finished streaming.
*/
onFinish?: (prompt: string, completion: string) => void
/**
* Callback function to be called when an error is encountered.
*/
onError?: (error: Error) => void
/**
* The credentials mode to be used for the fetch request.
* Possible values are: 'omit', 'same-origin', 'include'.
* Defaults to 'same-origin'.
*/
credentials?: RequestCredentials
/**
* HTTP headers to be sent with the API request.
*/
headers?: Record<string, string> | Headers
/**
* Extra body object to be sent with the API request.
* @example
* Send a `sessionId` to the API along with the prompt.
* ```js
* useChat({
* body: {
* sessionId: '123',
* }
* })
* ```
*/
body?: object
/** Stream mode (default to "stream-data") */
streamMode?: 'stream-data' | 'text'
}
export type JSONValue =
| null
| string
| number
| boolean
| { [x: string]: JSONValue }
| Array<JSONValue>
export type AssistantMessage = {
id: string
role: 'assistant'
content: Array<{
type: 'text'
text: {
value: string
}
}>
}
/*
* A data message is an application-specific message from the assistant
* that should be shown in order with the other messages.
*
* It can trigger other operations on the frontend, such as annotating
* a map.
*/
export type DataMessage = {
id?: string // optional id, implement if needed (e.g. for persistance)
role: 'data'
data: JSONValue // application-specific data
}

View File

@ -54,17 +54,12 @@ export const executeClientSideAction = async ({
'streamOpenAiChatCompletion' in clientSideAction ||
'stream' in clientSideAction
) {
const runtime =
'streamOpenAiChatCompletion' in clientSideAction
? clientSideAction.streamOpenAiChatCompletion.runtime
: clientSideAction.runtime
const { error, message } = await streamChat(context)({
messages:
'streamOpenAiChatCompletion' in clientSideAction
? clientSideAction.streamOpenAiChatCompletion?.messages
: undefined,
onMessageStream,
runtime,
})
if (error)
return {

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/nextjs",
"version": "0.2.77",
"version": "0.2.78",
"description": "Convenient library to display typebots on your Next.js website",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@ -35,7 +35,7 @@
"rollup-plugin-typescript-paths": "1.4.0",
"tslib": "2.6.0",
"tsx": "3.12.7",
"typescript": "5.3.2",
"typescript": "5.4.5",
"@rollup/plugin-typescript": "11.1.2"
},
"peerDependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/react",
"version": "0.2.77",
"version": "0.2.78",
"description": "Convenient library to display typebots on your React app",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@ -39,7 +39,7 @@
"rollup-plugin-typescript-paths": "1.4.0",
"tslib": "2.6.0",
"tsx": "3.12.7",
"typescript": "5.3.2",
"typescript": "5.4.5",
"@rollup/plugin-typescript": "11.1.2"
},
"peerDependencies": {

View File

@ -1,6 +1,6 @@
import { Anthropic } from '@anthropic-ai/sdk'
import { options as createMessageOptions } from '../actions/createChatMessage'
import { ReadOnlyVariableStore } from '@typebot.io/forge'
import { VariableStore } from '@typebot.io/forge'
import { isNotEmpty } from '@typebot.io/lib'
import { z } from '@typebot.io/forge/zod'
@ -9,7 +9,7 @@ export const parseChatMessages = ({
variables,
}: {
options: Pick<z.infer<typeof createMessageOptions>, 'messages'>
variables: ReadOnlyVariableStore
variables: VariableStore
}): Anthropic.Messages.MessageParam[] => {
const parsedMessages = messages
?.flatMap((message) => {

View File

@ -11,10 +11,10 @@
"@typebot.io/lib": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2"
"typescript": "5.4.5"
},
"dependencies": {
"@anthropic-ai/sdk": "0.18.0",
"ai": "3.0.12"
"@anthropic-ai/sdk": "0.20.6",
"ai": "3.0.31"
}
}

View File

@ -9,7 +9,7 @@
"@typebot.io/forge": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2",
"typescript": "5.4.5",
"@typebot.io/lib": "workspace:*"
}
}

View File

@ -10,7 +10,7 @@
"@typebot.io/lib": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2",
"typescript": "5.4.5",
"ky": "1.2.3"
}
}

View File

@ -11,6 +11,6 @@
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"ky": "1.2.3",
"typescript": "5.3.2"
"typescript": "5.4.5"
}
}

View File

@ -10,7 +10,7 @@
"@typebot.io/lib": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2"
"typescript": "5.4.5"
},
"dependencies": {
"ky": "1.2.3",

View File

@ -80,6 +80,7 @@ export const createChatCompletion = createAction({
blockId: 'anthropic',
transform: (options) => ({
...options,
model: undefined,
action: 'Create Chat Message',
responseMapping: options.responseMapping?.map((res: any) =>
res.item === 'Message content'

View File

@ -1,5 +1,5 @@
import { options as createChatCompletionOption } from '../actions/createChatCompletion'
import { ReadOnlyVariableStore } from '@typebot.io/forge'
import { VariableStore } from '@typebot.io/forge'
import { isDefined, isNotEmpty } from '@typebot.io/lib'
import { z } from '@typebot.io/forge/zod'
@ -8,7 +8,7 @@ export const parseMessages = ({
variables,
}: {
options: Pick<z.infer<typeof createChatCompletionOption>, 'messages'>
variables: ReadOnlyVariableStore
variables: VariableStore
}) =>
messages
?.flatMap((message) => {

View File

@ -11,9 +11,9 @@
"@typebot.io/tsconfig": "workspace:*",
"@types/node": "^20.12.4",
"@types/react": "18.2.15",
"typescript": "5.3.2"
"typescript": "5.4.5"
},
"dependencies": {
"ai": "3.0.12"
"ai": "3.0.31"
}
}

View File

@ -24,6 +24,7 @@ export const createChatCompletion = createAction({
blockId: 'anthropic',
transform: (options) => ({
...options,
model: undefined,
action: 'Create Chat Message',
responseMapping: options.responseMapping?.map((res: any) =>
res.item === 'Message content'

View File

@ -9,7 +9,7 @@
"@typebot.io/forge": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2",
"typescript": "5.4.5",
"@typebot.io/lib": "workspace:*",
"@typebot.io/openai-block": "workspace:*",
"ky": "1.2.3"

View File

@ -1,26 +1,37 @@
import { createAction, option } from '@typebot.io/forge'
import { isDefined, isEmpty } from '@typebot.io/lib'
import {
LogsStore,
VariableStore,
createAction,
option,
} from '@typebot.io/forge'
import { isDefined, isEmpty, isNotEmpty } from '@typebot.io/lib'
import { auth } from '../auth'
import { ClientOptions, OpenAI } from 'openai'
import { baseOptions } from '../baseOptions'
import { executeFunction } from '@typebot.io/variables/executeFunction'
import { readDataStream } from 'ai'
import { deprecatedAskAssistantOptions } from '../deprecated'
import { OpenAIAssistantStream } from '../helpers/OpenAIAssistantStream'
export const askAssistant = createAction({
auth,
baseOptions,
name: 'Ask Assistant',
options: option.object({
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({
threadVariableId: option.string.layout({
label: 'Thread ID',
moreInfoTooltip:
'Used to remember the conversation with the user. If empty, a new thread is created.',
inputType: 'variableDropdown',
}),
message: option.string.layout({
label: 'Message',
inputType: 'textarea',
@ -44,11 +55,14 @@ export const askAssistant = createAction({
)
.layout({ accordion: 'Functions', itemLabel: 'function' }),
responseMapping: option
.saveResponseArray(['Message', 'Thread ID'] as const)
.saveResponseArray(['Message', 'Thread ID'] as const, {
item: { hiddenItems: ['Thread ID'] },
})
.layout({
accordion: 'Save response',
}),
}),
})
.merge(deprecatedAskAssistantOptions),
fetchers: [
{
id: 'fetchAssistants',
@ -121,6 +135,23 @@ export const askAssistant = createAction({
getSetVariableIds: ({ responseMapping }) =>
responseMapping?.map((r) => r.variableId).filter(isDefined) ?? [],
run: {
stream: {
getStreamVariableId: ({ responseMapping }) =>
responseMapping?.find((m) => !m.item || m.item === 'Message')
?.variableId,
run: async ({ credentials, options, variables }) =>
createAssistantStream({
apiKey: credentials.apiKey,
assistantId: options.assistantId,
message: options.message,
baseUrl: options.baseUrl,
apiVersion: options.apiVersion,
threadVariableId: options.threadVariableId,
variables,
functions: options.functions,
responseMapping: options.responseMapping,
}),
},
server: async ({
credentials: { apiKey },
options: {
@ -130,17 +161,82 @@ export const askAssistant = createAction({
message,
responseMapping,
threadId,
threadVariableId,
functions,
},
variables,
logs,
}) => {
const stream = await createAssistantStream({
apiKey,
assistantId,
logs,
message,
baseUrl,
apiVersion,
threadVariableId,
variables,
threadId,
functions,
})
if (!stream) return
let writingMessage = ''
for await (const { type, value } of readDataStream(stream.getReader())) {
if (type === 'text') {
writingMessage += value
}
}
responseMapping?.forEach((mapping) => {
if (!mapping.variableId) return
if (!mapping.item || mapping.item === 'Message') {
variables.set(
mapping.variableId,
writingMessage.replace(/【.+】/g, '')
)
}
})
},
},
})
const createAssistantStream = async ({
apiKey,
assistantId,
logs,
message,
baseUrl,
apiVersion,
threadVariableId,
variables,
threadId,
functions,
responseMapping,
}: {
apiKey?: string
assistantId?: string
message?: string
baseUrl?: string
apiVersion?: string
threadVariableId?: string
threadId?: string
functions?: { name?: string; code?: string }[]
responseMapping?: {
item?: 'Thread ID' | 'Message' | undefined
variableId?: string | undefined
}[]
logs?: LogsStore
variables: VariableStore
}): Promise<ReadableStream | undefined> => {
if (isEmpty(assistantId)) {
logs.add('Assistant ID is empty')
logs?.add('Assistant ID is empty')
return
}
if (isEmpty(message)) {
logs.add('Message is empty')
logs?.add('Message is empty')
return
}
const config = {
@ -158,10 +254,30 @@ export const askAssistant = createAction({
const openai = new OpenAI(config)
// Create a thread if needed
const currentThreadId = isEmpty(threadId)
? (await openai.beta.threads.create({})).id
: threadId
let currentThreadId: string | undefined
if (
threadVariableId &&
isNotEmpty(variables.get(threadVariableId)?.toString())
) {
currentThreadId = variables.get(threadVariableId)?.toString()
} else if (isNotEmpty(threadId)) {
currentThreadId = threadId
} else {
currentThreadId = (await openai.beta.threads.create({})).id
const threadIdResponseMapping = responseMapping?.find(
(mapping) => mapping.item === 'Thread ID'
)
if (threadIdResponseMapping?.variableId)
variables.set(threadIdResponseMapping.variableId, currentThreadId)
if (threadVariableId) variables.set(threadVariableId, currentThreadId)
}
if (!currentThreadId) {
logs?.add('Could not get thread ID')
return
}
// Add a message to the thread
const createdMessage = await openai.beta.threads.messages.create(
@ -171,33 +287,25 @@ export const askAssistant = createAction({
content: message,
}
)
const run = await openai.beta.threads.runs.create(currentThreadId, {
return OpenAIAssistantStream(
{ threadId: currentThreadId, messageId: createdMessage.id },
async ({ forwardStream }) => {
const runStream = openai.beta.threads.runs.createAndStream(
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'
let runResult = await forwardStream(runStream)
while (
runResult?.status === 'requires_action' &&
runResult.required_action?.type === 'submit_tool_outputs'
) {
throw new Error(run.status)
}
if (run.status === 'requires_action') {
if (run.required_action?.type === 'submit_tool_outputs') {
const tool_outputs = (
await Promise.all(
run.required_action.submit_tool_outputs.tool_calls.map(
runResult.required_action.submit_tool_outputs.tool_calls.map(
async (toolCall) => {
const parameters = JSON.parse(toolCall.function.arguments)
@ -227,46 +335,14 @@ export const askAssistant = createAction({
)
)
).filter(isDefined)
run = await openai.beta.threads.runs.submitToolOutputs(
runResult = await forwardStream(
openai.beta.threads.runs.submitToolOutputsStream(
currentThreadId,
run.id,
runResult.id,
{ tool_outputs }
)
await waitForRun(run)
)
}
}
}
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.replace(/【.+】/g, '')
break
}
}
variables.set(mapping.variableId, message)
}
if (mapping.item === 'Thread ID')
variables.set(mapping.variableId, currentThreadId)
})
},
},
})
)
}

View File

@ -31,6 +31,7 @@ export const createChatCompletion = createAction({
blockId: 'anthropic',
transform: (options) => ({
...options,
model: undefined,
action: 'Create Chat Message',
responseMapping: options.responseMapping?.map((res: any) =>
res.item === 'Message content'

View File

@ -0,0 +1,10 @@
import { option } from '@typebot.io/forge'
export const deprecatedAskAssistantOptions = option.object({
threadId: option.string.layout({
label: 'Thread ID',
moreInfoTooltip:
'Used to remember the conversation with the user. If empty, a new thread is created.',
isHidden: true,
}),
})

View File

@ -0,0 +1,145 @@
import { AssistantMessage, DataMessage, formatStreamPart } from 'ai'
import { AssistantStream } from 'openai/lib/AssistantStream'
import { Run } from 'openai/resources/beta/threads/runs/runs'
/**
You can pass the thread and the latest message into the `AssistantResponse`. This establishes the context for the response.
*/
type AssistantResponseSettings = {
/**
The thread ID that the response is associated with.
*/
threadId: string
/**
The ID of the latest message that the response is associated with.
*/
messageId: string
}
/**
The process parameter is a callback in which you can run the assistant on threads, and send messages and data messages to the client.
*/
type AssistantResponseCallback = (options: {
/**
@deprecated use variable from outer scope instead.
*/
threadId: string
/**
@deprecated use variable from outer scope instead.
*/
messageId: string
/**
Forwards an assistant message (non-streaming) to the client.
*/
sendMessage: (message: AssistantMessage) => void
/**
Send a data message to the client. You can use this to provide information for rendering custom UIs while the assistant is processing the thread.
*/
sendDataMessage: (message: DataMessage) => void
/**
Forwards the assistant response stream to the client. Returns the `Run` object after it completes, or when it requires an action.
*/
forwardStream: (stream: AssistantStream) => Promise<Run | undefined>
}) => Promise<void>
export const OpenAIAssistantStream = (
{ threadId, messageId }: AssistantResponseSettings,
process: AssistantResponseCallback
) =>
new ReadableStream({
async start(controller) {
const textEncoder = new TextEncoder()
const sendMessage = (message: AssistantMessage) => {
controller.enqueue(
textEncoder.encode(formatStreamPart('assistant_message', message))
)
}
const sendDataMessage = (message: DataMessage) => {
controller.enqueue(
textEncoder.encode(formatStreamPart('data_message', message))
)
}
const sendError = (errorMessage: string) => {
controller.enqueue(
textEncoder.encode(formatStreamPart('error', errorMessage))
)
}
const forwardStream = async (stream: AssistantStream) => {
let result: Run | undefined = undefined
for await (const value of stream) {
switch (value.event) {
case 'thread.message.created': {
controller.enqueue(
textEncoder.encode(
formatStreamPart('assistant_message', {
id: value.data.id,
role: 'assistant',
content: [{ type: 'text', text: { value: '' } }],
})
)
)
break
}
case 'thread.message.delta': {
const content = value.data.delta.content?.[0]
if (content?.type === 'text' && content.text?.value != null) {
controller.enqueue(
textEncoder.encode(
formatStreamPart('text', content.text.value)
)
)
}
break
}
case 'thread.run.completed':
case 'thread.run.requires_action': {
result = value.data
break
}
}
}
return result
}
// send the threadId and messageId as the first message:
controller.enqueue(
textEncoder.encode(
formatStreamPart('assistant_control_data', {
threadId,
messageId,
})
)
)
try {
await process({
threadId,
messageId,
sendMessage,
sendDataMessage,
forwardStream,
})
} catch (error) {
sendError((error as any).message ?? `${error}`)
} finally {
controller.close()
}
},
pull(controller) {},
cancel() {},
})

View File

@ -1,5 +1,5 @@
import type { OpenAI } from 'openai'
import { ReadOnlyVariableStore } from '@typebot.io/forge'
import { VariableStore } from '@typebot.io/forge'
import { isNotEmpty } from '@typebot.io/lib'
import { ChatCompletionOptions } from '../shared/parseChatCompletionOptions'
@ -8,7 +8,7 @@ export const parseChatCompletionMessages = ({
variables,
}: {
options: ChatCompletionOptions
variables: ReadOnlyVariableStore
variables: VariableStore
}): OpenAI.Chat.ChatCompletionMessageParam[] => {
const parsedMessages = messages
?.flatMap((message) => {

View File

@ -7,14 +7,14 @@
"author": "Baptiste Arnaud",
"license": "ISC",
"dependencies": {
"ai": "3.0.12",
"openai": "4.28.4"
"ai": "3.0.31",
"openai": "4.38.3"
},
"devDependencies": {
"@typebot.io/forge": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2",
"typescript": "5.4.5",
"@typebot.io/lib": "workspace:*",
"@typebot.io/variables": "workspace:*"
}

View File

@ -1,4 +1,4 @@
import { LogsStore, ReadOnlyVariableStore } from '@typebot.io/forge/types'
import { VariableStore } from '@typebot.io/forge/types'
import { ChatCompletionOptions } from './parseChatCompletionOptions'
import { executeFunction } from '@typebot.io/variables/executeFunction'
import { OpenAIStream, ToolCallPayload } from 'ai'
@ -10,7 +10,7 @@ import { parseToolParameters } from '../helpers/parseToolParameters'
type Props = {
credentials: { apiKey?: string }
options: ChatCompletionOptions
variables: ReadOnlyVariableStore
variables: VariableStore
config: { baseUrl: string; defaultModel?: string }
}
export const runChatCompletionStream = async ({

View File

@ -11,7 +11,7 @@
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"@types/qrcode": "^1.5.3",
"typescript": "5.3.2"
"typescript": "5.4.5"
},
"dependencies": {
"qrcode": "^1.5.3"

View File

@ -26,6 +26,7 @@ export const createChatCompletion = createAction({
blockId: 'anthropic',
transform: (options) => ({
...options,
model: undefined,
action: 'Create Chat Message',
responseMapping: options.responseMapping?.map((res: any) =>
res.item === 'Message content'

View File

@ -12,6 +12,6 @@
"@typebot.io/variables": "workspace:*",
"@typebot.io/openai-block": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2"
"typescript": "5.4.5"
}
}

View File

@ -9,7 +9,7 @@
"@typebot.io/forge": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2",
"typescript": "5.4.5",
"@typebot.io/lib": "workspace:*",
"ky": "1.2.3"
}

View File

@ -30,8 +30,6 @@ export type FunctionToExecute = {
content: string
}
export type ReadOnlyVariableStore = Omit<VariableStore, 'set'>
export type TurnableIntoParam<T = {}> = {
blockId: string
/**
@ -65,7 +63,7 @@ export type ActionDefinition<
run: (params: {
credentials: CredentialsFromAuthDef<A>
options: z.infer<BaseOptions> & z.infer<Options>
variables: ReadOnlyVariableStore
variables: VariableStore
}) => Promise<ReadableStream<any> | undefined>
}
web?: {

View File

@ -17,7 +17,7 @@
"next": "14.1.0",
"nodemailer": "6.9.8",
"tslib": "2.6.0",
"typescript": "5.3.2"
"typescript": "5.4.5"
},
"peerDependencies": {
"next": "14.0.0",

View File

@ -22,6 +22,6 @@
"prisma": "5.12.1",
"@typebot.io/tsconfig": "workspace:*",
"tsx": "3.12.7",
"typescript": "5.3.2"
"typescript": "5.4.5"
}
}

View File

@ -13,6 +13,6 @@
"@typebot.io/prisma": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@typebot.io/env": "workspace:*",
"typescript": "5.3.2"
"typescript": "5.4.5"
}
}

View File

@ -110,7 +110,6 @@ export const clientSideActionSchema = z.discriminatedUnion('type', [
messages: z.array(
nativeMessageSchema.pick({ content: true, role: true })
),
runtime: z.enum(['edge', 'nodejs']),
}),
})
.merge(clientSideActionBaseSchema)
@ -152,7 +151,6 @@ export const clientSideActionSchema = z.discriminatedUnion('type', [
.object({
type: z.literal('stream'),
stream: z.literal(true),
runtime: z.enum(['edge', 'nodejs']),
})
.merge(clientSideActionBaseSchema)
.openapi({

View File

@ -14,6 +14,6 @@
"@typebot.io/forge-repository": "workspace:*",
"@typebot.io/prisma": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"typescript": "5.3.2"
"typescript": "5.4.5"
}
}

View File

@ -38,6 +38,7 @@ const inspectTypebot = async () => {
customDomain: true,
createdAt: true,
isArchived: true,
isClosed: true,
publishedTypebot: {
select: {
id: true,

View File

@ -46,7 +46,7 @@
"prompts": "2.4.2",
"stripe": "12.13.0",
"tsx": "3.12.7",
"typescript": "5.3.2",
"typescript": "5.4.5",
"zod": "3.22.4"
},
"dependencies": {

368
pnpm-lock.yaml generated
View File

@ -370,8 +370,8 @@ importers:
specifier: 1.12.4
version: 1.12.4
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
zod:
specifier: 3.22.4
version: 3.22.4
@ -418,14 +418,14 @@ importers:
specifier: workspace:*
version: link:../../packages/variables
ai:
specifier: 3.0.12
version: 3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
specifier: 3.0.31
version: 3.0.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
hono:
specifier: 4.0.5
version: 4.0.5
openai:
specifier: 4.28.4
version: 4.28.4
specifier: 4.38.3
version: 4.38.3
prom-client:
specifier: 15.1.0
version: 15.1.0
@ -570,8 +570,8 @@ importers:
specifier: 3.3.3
version: 3.3.3
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
apps/viewer:
dependencies:
@ -600,8 +600,8 @@ importers:
specifier: workspace:*
version: link:../../packages/prisma
ai:
specifier: 3.0.12
version: 3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
specifier: 3.0.31
version: 3.0.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
bot-engine:
specifier: workspace:*
version: link:../../packages/deprecated/bot-engine
@ -627,8 +627,8 @@ importers:
specifier: 6.9.8
version: 6.9.8
openai:
specifier: 4.28.4
version: 4.28.4
specifier: 4.38.3
version: 4.38.3
qs:
specifier: 6.11.2
version: 6.11.2
@ -724,8 +724,8 @@ importers:
specifier: 1.12.4
version: 1.12.4
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
zod:
specifier: 3.22.4
version: 3.22.4
@ -788,8 +788,8 @@ importers:
specifier: 30.4.5
version: 30.4.5(@types/react@18.2.15)(immer@10.0.2)(react-dom@18.2.0)(react@18.2.0)(scheduler@0.23.0)(slate-history@0.100.0)(slate-hyperscript@0.100.0)(slate-react@0.102.0)(slate@0.102.0)
ai:
specifier: 3.0.12
version: 3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
specifier: 3.0.31
version: 3.0.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
chrono-node:
specifier: 2.7.5
version: 2.7.5
@ -818,8 +818,8 @@ importers:
specifier: 6.9.8
version: 6.9.8
openai:
specifier: 4.28.4
version: 4.28.4
specifier: 4.38.3
version: 4.38.3
qs:
specifier: 6.11.2
version: 6.11.2
@ -932,13 +932,13 @@ importers:
version: 3.2.4(postcss@8.4.21)
tsup:
specifier: 6.5.0
version: 6.5.0(postcss@8.4.21)(typescript@5.3.2)
version: 6.5.0(postcss@8.4.21)(typescript@5.4.5)
typebot-js:
specifier: workspace:*
version: link:../typebot-js
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/deprecated/typebot-js:
devDependencies:
@ -965,13 +965,13 @@ importers:
version: 2.8.3
ts-jest:
specifier: 29.0.5
version: 29.0.5(@babel/core@7.22.9)(esbuild@0.15.18)(jest@29.4.1)(typescript@5.3.2)
version: 29.0.5(@babel/core@7.22.9)(esbuild@0.15.18)(jest@29.4.1)(typescript@5.4.5)
tsup:
specifier: 6.5.0
version: 6.5.0(typescript@5.3.2)
version: 6.5.0(typescript@5.4.5)
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/emails:
devDependencies:
@ -1056,7 +1056,7 @@ importers:
version: 0.4.3(rollup@3.26.2)
'@rollup/plugin-typescript':
specifier: 11.1.2
version: 11.1.2(rollup@3.26.2)(tslib@2.6.0)(typescript@5.3.2)
version: 11.1.2(rollup@3.26.2)(tslib@2.6.0)(typescript@5.4.5)
'@typebot.io/bot-engine':
specifier: workspace:*
version: link:../../bot-engine
@ -1095,7 +1095,7 @@ importers:
version: link:../../eslint-config-custom
eslint-plugin-solid:
specifier: 0.12.1
version: 0.12.1(eslint@8.44.0)(typescript@5.3.2)
version: 0.12.1(eslint@8.44.0)(typescript@5.4.5)
postcss:
specifier: 8.4.26
version: 8.4.26
@ -1110,13 +1110,13 @@ importers:
version: 4.0.2(postcss@8.4.26)
rollup-plugin-typescript-paths:
specifier: 1.4.0
version: 1.4.0(typescript@5.3.2)
version: 1.4.0(typescript@5.4.5)
tailwindcss:
specifier: 3.3.3
version: 3.3.3
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/embeds/nextjs:
dependencies:
@ -1141,7 +1141,7 @@ importers:
version: 0.4.3(rollup@3.26.2)
'@rollup/plugin-typescript':
specifier: 11.1.2
version: 11.1.2(rollup@3.26.2)(tslib@2.6.0)(typescript@5.3.2)
version: 11.1.2(rollup@3.26.2)(tslib@2.6.0)(typescript@5.4.5)
'@typebot.io/js':
specifier: workspace:*
version: link:../js
@ -1180,7 +1180,7 @@ importers:
version: 3.26.2
rollup-plugin-typescript-paths:
specifier: 1.4.0
version: 1.4.0(typescript@5.3.2)
version: 1.4.0(typescript@5.4.5)
tslib:
specifier: 2.6.0
version: 2.6.0
@ -1188,14 +1188,14 @@ importers:
specifier: 3.12.7
version: 3.12.7
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/embeds/react:
dependencies:
'@ladle/react':
specifier: 2.5.1
version: 2.5.1(@types/node@20.4.2)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.2)
version: 2.5.1(@types/node@20.4.2)(react-dom@18.2.0)(react@18.2.0)(typescript@5.4.5)
devDependencies:
'@babel/preset-react':
specifier: 7.22.5
@ -1214,7 +1214,7 @@ importers:
version: 0.4.3(rollup@3.26.2)
'@rollup/plugin-typescript':
specifier: 11.1.2
version: 11.1.2(rollup@3.26.2)(tslib@2.6.0)(typescript@5.3.2)
version: 11.1.2(rollup@3.26.2)(tslib@2.6.0)(typescript@5.4.5)
'@typebot.io/js':
specifier: workspace:*
version: link:../js
@ -1250,7 +1250,7 @@ importers:
version: 3.26.2
rollup-plugin-typescript-paths:
specifier: 1.4.0
version: 1.4.0(typescript@5.3.2)
version: 1.4.0(typescript@5.4.5)
tslib:
specifier: 2.6.0
version: 2.6.0
@ -1258,8 +1258,8 @@ importers:
specifier: 3.12.7
version: 3.12.7
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/embeds/wordpress: {}
@ -1289,7 +1289,7 @@ importers:
version: 8.44.0
eslint-config-next:
specifier: 13.4.9
version: 13.4.9(eslint@8.44.0)(typescript@5.3.2)
version: 13.4.9(eslint@8.44.0)(typescript@5.4.5)
eslint-config-prettier:
specifier: 8.8.0
version: 8.8.0(eslint@8.44.0)
@ -1299,19 +1299,19 @@ importers:
devDependencies:
'@typescript-eslint/eslint-plugin':
specifier: 6.0.0
version: 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.44.0)(typescript@5.3.2)
version: 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.44.0)(typescript@5.4.5)
'@typescript-eslint/parser':
specifier: 6.0.0
version: 6.0.0(eslint@8.44.0)(typescript@5.3.2)
version: 6.0.0(eslint@8.44.0)(typescript@5.4.5)
packages/forge/blocks/anthropic:
dependencies:
'@anthropic-ai/sdk':
specifier: 0.18.0
version: 0.18.0
specifier: 0.20.6
version: 0.20.6
ai:
specifier: 3.0.12
version: 3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
specifier: 3.0.31
version: 3.0.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
devDependencies:
'@typebot.io/forge':
specifier: workspace:*
@ -1326,8 +1326,8 @@ importers:
specifier: 18.2.15
version: 18.2.15
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/calCom:
devDependencies:
@ -1344,8 +1344,8 @@ importers:
specifier: 18.2.15
version: 18.2.15
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/chatNode:
devDependencies:
@ -1365,8 +1365,8 @@ importers:
specifier: 1.2.3
version: 1.2.3
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/difyAi:
devDependencies:
@ -1386,8 +1386,8 @@ importers:
specifier: 1.2.3
version: 1.2.3
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/elevenlabs:
dependencies:
@ -1408,14 +1408,14 @@ importers:
specifier: 18.2.15
version: 18.2.15
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/mistral:
dependencies:
ai:
specifier: 3.0.12
version: 3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
specifier: 3.0.31
version: 3.0.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
devDependencies:
'@typebot.io/forge':
specifier: workspace:*
@ -1433,8 +1433,8 @@ importers:
specifier: 18.2.15
version: 18.2.15
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/openRouter:
devDependencies:
@ -1457,17 +1457,17 @@ importers:
specifier: 1.2.3
version: 1.2.3
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/openai:
dependencies:
ai:
specifier: 3.0.12
version: 3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
specifier: 3.0.31
version: 3.0.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
openai:
specifier: 4.28.4
version: 4.28.4
specifier: 4.38.3
version: 4.38.3
devDependencies:
'@typebot.io/forge':
specifier: workspace:*
@ -1485,8 +1485,8 @@ importers:
specifier: 18.2.15
version: 18.2.15
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/qrcode:
dependencies:
@ -1510,8 +1510,8 @@ importers:
specifier: 18.2.15
version: 18.2.15
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/togetherAi:
devDependencies:
@ -1534,8 +1534,8 @@ importers:
specifier: 18.2.15
version: 18.2.15
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/blocks/zemanticAi:
devDependencies:
@ -1555,8 +1555,8 @@ importers:
specifier: 1.2.3
version: 1.2.3
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/forge/cli:
devDependencies:
@ -1731,8 +1731,8 @@ importers:
specifier: 2.6.0
version: 2.6.0
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/migrations:
dependencies:
@ -1794,8 +1794,8 @@ importers:
specifier: 3.12.7
version: 3.12.7
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/radar:
dependencies:
@ -1816,8 +1816,8 @@ importers:
specifier: workspace:*
version: link:../tsconfig
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/results:
dependencies:
@ -1857,8 +1857,8 @@ importers:
specifier: workspace:*
version: link:../tsconfig
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
packages/scripts:
dependencies:
@ -1924,8 +1924,8 @@ importers:
specifier: 3.12.7
version: 3.12.7
typescript:
specifier: 5.3.2
version: 5.3.2
specifier: 5.4.5
version: 5.4.5
zod:
specifier: 3.22.4
version: 3.22.4
@ -1988,6 +1988,29 @@ packages:
resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
engines: {node: '>=0.10.0'}
/@ai-sdk/provider-utils@0.0.3(zod@3.22.4):
resolution: {integrity: sha512-13+4v62ylduGvwz8966SdnT1aoQRO4QkWzZJyVswdgmYeX2vrXuU4bssK578+FXIXc1jwi2hLZO8lqgLPT/xDA==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.0.0
peerDependenciesMeta:
zod:
optional: true
dependencies:
'@ai-sdk/provider': 0.0.2
eventsource-parser: 1.1.2
nanoid: 3.3.6
secure-json-parse: 2.7.0
zod: 3.22.4
dev: false
/@ai-sdk/provider@0.0.2:
resolution: {integrity: sha512-LDRx7TFWjuuW1V8bGCMvOk4ap5gNGeSxa6w65Y+pHskiLRk/nn+Z2xzMy1JjCTksUblu0i/plai4bOLgqkxJHA==}
engines: {node: '>=18'}
dependencies:
json-schema: 0.4.0
dev: false
/@alloc/quick-lru@5.2.0:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
@ -1999,14 +2022,13 @@ packages:
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.25
/@anthropic-ai/sdk@0.18.0:
resolution: {integrity: sha512-3XsWEn/4nPGRd4AdSguugbSDFy6Z2AWTNOeI3iK+aV22+w23+vY9CEb3Hiy0kvKIQuxSmZz/+5WKC8nPWy8gVg==}
/@anthropic-ai/sdk@0.20.6:
resolution: {integrity: sha512-vpVWAol+Ih1UkZGUj8DYPuqWDGxBp6M/JYz4nvq2HBT0zKdvi24Z9oznA7tr+HDed78JZrw+nbxs2I8JbTAIiQ==}
dependencies:
'@types/node': 18.11.18
'@types/node-fetch': 2.6.11
abort-controller: 3.0.0
agentkeepalive: 4.5.0
digest-fetch: 1.3.0
form-data-encoder: 1.7.2
formdata-node: 4.4.1
node-fetch: 2.7.0
@ -7147,7 +7169,7 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
/@ladle/react@2.5.1(@types/node@20.4.2)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.2):
/@ladle/react@2.5.1(@types/node@20.4.2)(react-dom@18.2.0)(react@18.2.0)(typescript@5.4.5):
resolution: {integrity: sha512-xTSs5dUIK+zQzHNo6i3SDuA9lu0k8nUJ7/RNeNJ7oTkX05FfBSxCUeIKeUAjaVNm/axvylVhdGDm+yLBIxq8EA==}
engines: {node: '>=16.0.0'}
hasBin: true
@ -7191,7 +7213,7 @@ packages:
react-frame-component: 5.2.6(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)
react-inspector: 6.0.2(react@18.2.0)
vite: 4.5.2(@types/node@20.4.2)
vite-tsconfig-paths: 4.3.1(typescript@5.3.2)(vite@4.5.2)
vite-tsconfig-paths: 4.3.1(typescript@5.4.5)(vite@4.5.2)
transitivePeerDependencies:
- '@types/node'
- less
@ -7543,7 +7565,7 @@ packages:
lodash: 4.17.21
openapi-types: 12.1.3
zod: 3.22.4
zod-to-json-schema: 3.22.4(zod@3.22.4)
zod-to-json-schema: 3.22.5(zod@3.22.4)
dev: true
/@next/env@14.0.5-canary.46:
@ -8893,7 +8915,7 @@ packages:
terser: 5.29.1
dev: true
/@rollup/plugin-typescript@11.1.2(rollup@3.26.2)(tslib@2.6.0)(typescript@5.3.2):
/@rollup/plugin-typescript@11.1.2(rollup@3.26.2)(tslib@2.6.0)(typescript@5.4.5):
resolution: {integrity: sha512-0ghSOCMcA7fl1JM+0gYRf+Q/HWyg+zg7/gDSc+fRLmlJWcW5K1I+CLRzaRhXf4Y3DRyPnnDo4M2ktw+a6JcDEg==}
engines: {node: '>=14.0.0'}
peerDependencies:
@ -8910,7 +8932,7 @@ packages:
resolve: 1.22.8
rollup: 3.26.2
tslib: 2.6.0
typescript: 5.3.2
typescript: 5.4.5
dev: true
/@rollup/pluginutils@5.1.0(rollup@2.78.0):
@ -9973,7 +9995,7 @@ packages:
'@types/yargs-parser': 21.0.3
dev: true
/@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.44.0)(typescript@5.3.2):
/@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.44.0)(typescript@5.4.5):
resolution: {integrity: sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@ -9985,10 +10007,10 @@ packages:
optional: true
dependencies:
'@eslint-community/regexpp': 4.10.0
'@typescript-eslint/parser': 6.0.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/parser': 6.0.0(eslint@8.44.0)(typescript@5.4.5)
'@typescript-eslint/scope-manager': 6.0.0
'@typescript-eslint/type-utils': 6.0.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/utils': 6.0.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/type-utils': 6.0.0(eslint@8.44.0)(typescript@5.4.5)
'@typescript-eslint/utils': 6.0.0(eslint@8.44.0)(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 6.0.0
debug: 4.3.4
eslint: 8.44.0
@ -9998,13 +10020,13 @@ packages:
natural-compare: 1.4.0
natural-compare-lite: 1.4.0
semver: 7.6.0
ts-api-utils: 1.3.0(typescript@5.3.2)
typescript: 5.3.2
ts-api-utils: 1.3.0(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/parser@5.62.0(eslint@8.44.0)(typescript@5.3.2):
/@typescript-eslint/parser@5.62.0(eslint@8.44.0)(typescript@5.4.5):
resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -10016,15 +10038,15 @@ packages:
dependencies:
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.2)
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.5)
debug: 4.3.4
eslint: 8.44.0
typescript: 5.3.2
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: false
/@typescript-eslint/parser@6.0.0(eslint@8.44.0)(typescript@5.3.2):
/@typescript-eslint/parser@6.0.0(eslint@8.44.0)(typescript@5.4.5):
resolution: {integrity: sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@ -10036,11 +10058,11 @@ packages:
dependencies:
'@typescript-eslint/scope-manager': 6.0.0
'@typescript-eslint/types': 6.0.0
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.3.2)
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 6.0.0
debug: 4.3.4
eslint: 8.44.0
typescript: 5.3.2
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
@ -10058,7 +10080,7 @@ packages:
'@typescript-eslint/types': 6.0.0
'@typescript-eslint/visitor-keys': 6.0.0
/@typescript-eslint/type-utils@6.0.0(eslint@8.44.0)(typescript@5.3.2):
/@typescript-eslint/type-utils@6.0.0(eslint@8.44.0)(typescript@5.4.5):
resolution: {integrity: sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@ -10068,12 +10090,12 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.3.2)
'@typescript-eslint/utils': 6.0.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.4.5)
'@typescript-eslint/utils': 6.0.0(eslint@8.44.0)(typescript@5.4.5)
debug: 4.3.4
eslint: 8.44.0
ts-api-utils: 1.3.0(typescript@5.3.2)
typescript: 5.3.2
ts-api-utils: 1.3.0(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
dev: true
@ -10086,7 +10108,7 @@ packages:
resolution: {integrity: sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==}
engines: {node: ^16.0.0 || >=18.0.0}
/@typescript-eslint/typescript-estree@5.62.0(typescript@5.3.2):
/@typescript-eslint/typescript-estree@5.62.0(typescript@5.4.5):
resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -10101,12 +10123,12 @@ packages:
globby: 11.1.0
is-glob: 4.0.3
semver: 7.6.0
tsutils: 3.21.0(typescript@5.3.2)
typescript: 5.3.2
tsutils: 3.21.0(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
/@typescript-eslint/typescript-estree@6.0.0(typescript@5.3.2):
/@typescript-eslint/typescript-estree@6.0.0(typescript@5.4.5):
resolution: {integrity: sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@ -10121,12 +10143,12 @@ packages:
globby: 11.1.0
is-glob: 4.0.3
semver: 7.6.0
ts-api-utils: 1.3.0(typescript@5.3.2)
typescript: 5.3.2
ts-api-utils: 1.3.0(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
/@typescript-eslint/utils@5.62.0(eslint@8.44.0)(typescript@5.3.2):
/@typescript-eslint/utils@5.62.0(eslint@8.44.0)(typescript@5.4.5):
resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -10137,7 +10159,7 @@ packages:
'@types/semver': 7.5.8
'@typescript-eslint/scope-manager': 5.62.0
'@typescript-eslint/types': 5.62.0
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.2)
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.4.5)
eslint: 8.44.0
eslint-scope: 5.1.1
semver: 7.6.0
@ -10146,7 +10168,7 @@ packages:
- typescript
dev: true
/@typescript-eslint/utils@6.0.0(eslint@8.44.0)(typescript@5.3.2):
/@typescript-eslint/utils@6.0.0(eslint@8.44.0)(typescript@5.4.5):
resolution: {integrity: sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
@ -10157,7 +10179,7 @@ packages:
'@types/semver': 7.5.8
'@typescript-eslint/scope-manager': 6.0.0
'@typescript-eslint/types': 6.0.0
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.3.2)
'@typescript-eslint/typescript-estree': 6.0.0(typescript@5.4.5)
eslint: 8.44.0
eslint-scope: 5.1.1
semver: 7.6.0
@ -10857,7 +10879,7 @@ packages:
dependencies:
'@vue/compiler-ssr': 3.4.21
'@vue/shared': 3.4.21
vue: 3.4.21(typescript@5.3.2)
vue: 3.4.21(typescript@5.4.5)
dev: false
/@vue/shared@3.4.21:
@ -11098,9 +11120,9 @@ packages:
indent-string: 5.0.0
dev: true
/ai@3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4):
resolution: {integrity: sha512-cP/Moag7PcDOE3kA7WU00YS+mQiuPpAxY+uf57lkWwnqSB1K3/RzwnRF+LD1FqgJfCubI4WEbajMPbnnCr8lAg==}
engines: {node: '>=14.6'}
/ai@3.0.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4):
resolution: {integrity: sha512-SmwVgBcTLchKTcQjFYRskCkw9H9p/PivUxAQzqIT+aX97kfBr3uBw3nFOH+RKseCsVEMt3w27K2h9n2u0bskZA==}
engines: {node: '>=18'}
peerDependencies:
react: ^18.2.0
solid-js: ^1.7.7
@ -11119,10 +11141,14 @@ packages:
zod:
optional: true
dependencies:
eventsource-parser: 1.0.0
'@ai-sdk/provider': 0.0.2
'@ai-sdk/provider-utils': 0.0.3(zod@3.22.4)
eventsource-parser: 1.1.2
json-schema: 0.4.0
jsondiffpatch: 0.6.0
nanoid: 3.3.6
react: 18.2.0
secure-json-parse: 2.7.0
solid-js: 1.7.8
solid-swr-store: 0.10.7(solid-js@1.7.8)(swr-store@0.10.6)
sswr: 2.0.0(svelte@4.2.12)
@ -11130,9 +11156,9 @@ packages:
swr: 2.2.0(react@18.2.0)
swr-store: 0.10.6
swrv: 1.0.4(vue@3.4.21)
vue: 3.4.21(typescript@5.3.2)
vue: 3.4.21(typescript@5.4.5)
zod: 3.22.4
zod-to-json-schema: 3.22.4(zod@3.22.4)
zod-to-json-schema: 3.22.5(zod@3.22.4)
dev: false
/ajv-draft-04@1.0.0(ajv@8.12.0):
@ -13844,7 +13870,7 @@ packages:
source-map: 0.6.1
dev: true
/eslint-config-next@13.4.9(eslint@8.44.0)(typescript@5.3.2):
/eslint-config-next@13.4.9(eslint@8.44.0)(typescript@5.4.5):
resolution: {integrity: sha512-0fLtKRR268NArpqeXXwnLgMXPvF64YESQvptVg+RMLCaijKm3FICN9Y7Jc1p2o+yrWwE4DufJXDM/Vo53D1L7g==}
peerDependencies:
eslint: ^7.23.0 || ^8.0.0
@ -13855,7 +13881,7 @@ packages:
dependencies:
'@next/eslint-plugin-next': 13.4.9
'@rushstack/eslint-patch': 1.7.2
'@typescript-eslint/parser': 5.62.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/parser': 5.62.0(eslint@8.44.0)(typescript@5.4.5)
eslint: 8.44.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.44.0)
@ -13863,7 +13889,7 @@ packages:
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.44.0)
eslint-plugin-react: 7.32.2(eslint@8.44.0)
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.44.0)
typescript: 5.3.2
typescript: 5.4.5
transitivePeerDependencies:
- eslint-import-resolver-webpack
- supports-color
@ -13950,7 +13976,7 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 5.62.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/parser': 5.62.0(eslint@8.44.0)(typescript@5.4.5)
debug: 3.2.7
eslint: 8.44.0
eslint-import-resolver-node: 0.3.9
@ -13980,7 +14006,7 @@ packages:
eslint-import-resolver-webpack:
optional: true
dependencies:
'@typescript-eslint/parser': 6.0.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/parser': 6.0.0(eslint@8.44.0)(typescript@5.4.5)
debug: 3.2.7
eslint: 8.44.0
eslint-import-resolver-node: 0.3.9
@ -13998,7 +14024,7 @@ packages:
'@typescript-eslint/parser':
optional: true
dependencies:
'@typescript-eslint/parser': 6.0.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/parser': 6.0.0(eslint@8.44.0)(typescript@5.4.5)
array-includes: 3.1.7
array.prototype.findlastindex: 1.2.4
array.prototype.flat: 1.3.2
@ -14081,13 +14107,13 @@ packages:
string.prototype.matchall: 4.0.10
dev: false
/eslint-plugin-solid@0.12.1(eslint@8.44.0)(typescript@5.3.2):
/eslint-plugin-solid@0.12.1(eslint@8.44.0)(typescript@5.4.5):
resolution: {integrity: sha512-fM0sEg9PcS1mcNbWklwc+W/lOv1/XyEwXf53HmFFy4GOA8E3u41h8JW+hc+Vv1m3kh01umKoTalOTET08zKdAQ==}
engines: {node: '>=12.0.0'}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
'@typescript-eslint/utils': 5.62.0(eslint@8.44.0)(typescript@5.3.2)
'@typescript-eslint/utils': 5.62.0(eslint@8.44.0)(typescript@5.4.5)
eslint: 8.44.0
is-html: 2.0.0
jsx-ast-utils: 3.3.5
@ -14355,8 +14381,8 @@ packages:
engines: {node: '>=0.8.x'}
dev: false
/eventsource-parser@1.0.0:
resolution: {integrity: sha512-9jgfSCa3dmEme2ES3mPByGXfgZ87VbP97tng1G2nWwWx6bV2nYxm2AWCrbQjXToSe+yYlqaZNtxffR9IeQr95g==}
/eventsource-parser@1.1.2:
resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==}
engines: {node: '>=14.18'}
dev: false
@ -16676,6 +16702,10 @@ packages:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
dev: true
/json-schema@0.4.0:
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
dev: false
/json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@ -18918,6 +18948,22 @@ packages:
- encoding
dev: false
/openai@4.38.3:
resolution: {integrity: sha512-mIL9WtrFNOanpx98mJ+X/wkoepcxdqqu0noWFoNQHl/yODQ47YM7NEYda7qp8JfjqpLFVxY9mQhshoS/Fqac0A==}
hasBin: true
dependencies:
'@types/node': 18.11.18
'@types/node-fetch': 2.6.11
abort-controller: 3.0.0
agentkeepalive: 4.5.0
form-data-encoder: 1.7.2
formdata-node: 4.4.1
node-fetch: 2.7.0
web-streams-polyfill: 3.3.3
transitivePeerDependencies:
- encoding
dev: false
/openapi-types@12.1.3:
resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==}
dev: true
@ -20758,12 +20804,12 @@ packages:
- ts-node
dev: true
/rollup-plugin-typescript-paths@1.4.0(typescript@5.3.2):
/rollup-plugin-typescript-paths@1.4.0(typescript@5.4.5):
resolution: {integrity: sha512-6EgeLRjTVmymftEyCuYu91XzY5XMB5lR0YrJkeT0D7OG2RGSdbNL+C/hfPIdc/sjMa9Sl5NLsxIr6C/+/5EUpA==}
peerDependencies:
typescript: '>=3.4'
dependencies:
typescript: 5.3.2
typescript: 5.4.5
dev: true
/rollup-pluginutils@2.8.2:
@ -20930,6 +20976,10 @@ packages:
resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==}
dev: true
/secure-json-parse@2.7.0:
resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
dev: false
/selderee@0.11.0:
resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==}
dependencies:
@ -21788,7 +21838,7 @@ packages:
peerDependencies:
vue: '>=3.2.26 < 4'
dependencies:
vue: 3.4.21(typescript@5.3.2)
vue: 3.4.21(typescript@5.4.5)
dev: false
/symbol-observable@1.0.1:
@ -22128,13 +22178,13 @@ packages:
/trough@2.2.0:
resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
/ts-api-utils@1.3.0(typescript@5.3.2):
/ts-api-utils@1.3.0(typescript@5.4.5):
resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
engines: {node: '>=16'}
peerDependencies:
typescript: '>=4.2.0'
dependencies:
typescript: 5.3.2
typescript: 5.4.5
/ts-easing@0.2.0:
resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==}
@ -22143,7 +22193,7 @@ packages:
/ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
/ts-jest@29.0.5(@babel/core@7.22.9)(esbuild@0.15.18)(jest@29.4.1)(typescript@5.3.2):
/ts-jest@29.0.5(@babel/core@7.22.9)(esbuild@0.15.18)(jest@29.4.1)(typescript@5.4.5):
resolution: {integrity: sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@ -22174,11 +22224,11 @@ packages:
lodash.memoize: 4.1.2
make-error: 1.3.6
semver: 7.6.0
typescript: 5.3.2
typescript: 5.4.5
yargs-parser: 21.1.1
dev: true
/tsconfck@3.0.3(typescript@5.3.2):
/tsconfck@3.0.3(typescript@5.4.5):
resolution: {integrity: sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==}
engines: {node: ^18 || >=20}
hasBin: true
@ -22188,7 +22238,7 @@ packages:
typescript:
optional: true
dependencies:
typescript: 5.3.2
typescript: 5.4.5
dev: false
/tsconfig-paths@3.15.0:
@ -22210,7 +22260,7 @@ packages:
/tslib@2.6.0:
resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==}
/tsup@6.5.0(postcss@8.4.21)(typescript@5.3.2):
/tsup@6.5.0(postcss@8.4.21)(typescript@5.4.5):
resolution: {integrity: sha512-36u82r7rYqRHFkD15R20Cd4ercPkbYmuvRkz3Q1LCm5BsiFNUgpo36zbjVhCOgvjyxNBWNKHsaD5Rl8SykfzNA==}
engines: {node: '>=14'}
hasBin: true
@ -22241,13 +22291,13 @@ packages:
source-map: 0.8.0-beta.0
sucrase: 3.35.0
tree-kill: 1.2.2
typescript: 5.3.2
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
- ts-node
dev: true
/tsup@6.5.0(typescript@5.3.2):
/tsup@6.5.0(typescript@5.4.5):
resolution: {integrity: sha512-36u82r7rYqRHFkD15R20Cd4ercPkbYmuvRkz3Q1LCm5BsiFNUgpo36zbjVhCOgvjyxNBWNKHsaD5Rl8SykfzNA==}
engines: {node: '>=14'}
hasBin: true
@ -22277,20 +22327,20 @@ packages:
source-map: 0.8.0-beta.0
sucrase: 3.35.0
tree-kill: 1.2.2
typescript: 5.3.2
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
- ts-node
dev: true
/tsutils@3.21.0(typescript@5.3.2):
/tsutils@3.21.0(typescript@5.4.5):
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
engines: {node: '>= 6'}
peerDependencies:
typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
dependencies:
tslib: 1.14.1
typescript: 5.3.2
typescript: 5.4.5
/tsx@3.12.7:
resolution: {integrity: sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==}
@ -22470,8 +22520,8 @@ packages:
hasBin: true
dev: false
/typescript@5.3.2:
resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==}
/typescript@5.4.5:
resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==}
engines: {node: '>=14.17'}
hasBin: true
@ -22914,7 +22964,7 @@ packages:
vfile-message: 4.0.2
dev: false
/vite-tsconfig-paths@4.3.1(typescript@5.3.2)(vite@4.5.2):
/vite-tsconfig-paths@4.3.1(typescript@5.4.5)(vite@4.5.2):
resolution: {integrity: sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==}
peerDependencies:
vite: '*'
@ -22924,7 +22974,7 @@ packages:
dependencies:
debug: 4.3.4
globrex: 0.1.2
tsconfck: 3.0.3(typescript@5.3.2)
tsconfck: 3.0.3(typescript@5.4.5)
vite: 4.5.2(@types/node@20.4.2)
transitivePeerDependencies:
- supports-color
@ -22975,7 +23025,7 @@ packages:
resolution: {integrity: sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg==}
dev: true
/vue@3.4.21(typescript@5.3.2):
/vue@3.4.21(typescript@5.4.5):
resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==}
peerDependencies:
typescript: '*'
@ -22988,7 +23038,7 @@ packages:
'@vue/runtime-dom': 3.4.21
'@vue/server-renderer': 3.4.21(vue@3.4.21)
'@vue/shared': 3.4.21
typescript: 5.3.2
typescript: 5.4.5
dev: false
/w3c-keyname@2.2.8:
@ -23423,8 +23473,8 @@ packages:
zod: 3.22.4
dev: false
/zod-to-json-schema@3.22.4(zod@3.22.4):
resolution: {integrity: sha512-2Ed5dJ+n/O3cU383xSY28cuVi0BCQhF8nYqWU5paEpl7fVdqdAmiLdqLyfblbNdfOFwFfi/mqU4O1pwc60iBhQ==}
/zod-to-json-schema@3.22.5(zod@3.22.4):
resolution: {integrity: sha512-+akaPo6a0zpVCCseDed504KBJUQpEW5QZw7RMneNmKw+fGaML1Z9tUNLnHHAC8x6dzVRO1eB2oEMyZRnuBZg7Q==}
peerDependencies:
zod: ^3.22.4
dependencies: