From ebb3ffd7007929ae8e636bbcc4505166b5ab42b2 Mon Sep 17 00:00:00 2001 From: Ben Teichman Date: Fri, 20 Dec 2024 17:01:45 -0500 Subject: [PATCH 1/5] feat: baseline streaming (DSN-2619) --- packages/sdk-runtime/src/main.ts | 1 + packages/sdk-runtime/src/runtime.client.ts | 65 ++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 packages/sdk-runtime/src/runtime.client.ts diff --git a/packages/sdk-runtime/src/main.ts b/packages/sdk-runtime/src/main.ts index 68c113d19d..b4750c8235 100644 --- a/packages/sdk-runtime/src/main.ts +++ b/packages/sdk-runtime/src/main.ts @@ -1,3 +1,4 @@ export * from './runtime'; +export * from './runtime.client'; export * from './sdk'; export * from './trace'; diff --git a/packages/sdk-runtime/src/runtime.client.ts b/packages/sdk-runtime/src/runtime.client.ts new file mode 100644 index 0000000000..71316cc45b --- /dev/null +++ b/packages/sdk-runtime/src/runtime.client.ts @@ -0,0 +1,65 @@ +import type { Trace } from '@voiceflow/base-types'; +import { FetchClient } from '@voiceflow/fetch'; +import { createParser, type EventSourceMessage } from 'eventsource-parser'; + +import type { RuntimeAction } from './runtime'; + +export interface RuntimeClientOptions { + baseURL: string; +} + +export interface InteractStreamRequest { + projectID: string; + userID: string; + environment?: string; + + action: RuntimeAction; +} + +export class RuntimeClient { + private readonly fetch = new FetchClient({ baseURL: this.options.baseURL }); + + constructor(private readonly options: RuntimeClientOptions) {} + + async interactStream({ projectID, userID, environment, action }: InteractStreamRequest) { + const result = await this.fetch.post( + `/v2/public/project/${projectID}/user/${encodeURIComponent(userID)}/interact/stream`, + { + query: new URLSearchParams({ + completion_events: String(true), + ...(environment && { environment }), + }), + json: { action }, + } + ); + + if (!result.body) { + throw new Error('interact stream body is empty'); + } + + const traces = new WritableStream(); + const parser = createParser({ + onEvent: (event: EventSourceMessage) => { + traces.getWriter().write(JSON.parse(event.data)); + }, + }); + const decoder = new TextDecoder(); + + const process = async () => { + for await (const chunk of result.body!) { + const text = decoder.decode(chunk, { stream: true }); + + parser.feed(text); + } + + await traces.close(); + }; + + process().catch(async (err) => { + console.error(err); + await traces.abort(); + }); + + return traces; + } +} From db01624cf52d8b48df36e601aca52b726cc4d622 Mon Sep 17 00:00:00 2001 From: Ben Teichman Date: Thu, 2 Jan 2025 20:03:19 -0500 Subject: [PATCH 2/5] feat: working simple streaming (DSN-2619) --- .../src/components/ChatScript/index.tsx | 6 +- apps/documentation/src/pages/_meta.js | 2 +- eslint.config.mjs | 4 +- packages/chat/package.json | 3 + .../src/components/AgentMessage/index.tsx | 89 ++ .../SystemResponse/SystemMessage.tsx | 10 + .../components/SystemResponse/constants.ts | 1 + .../src/components/SystemResponse/index.tsx | 35 +- .../src/components/SystemResponse/types.ts | 10 + .../traces/StreamedMessage.trace.ts | 105 +++ .../contexts/RuntimeContext/useRuntimeAPI.ts | 20 +- .../RuntimeContext/useRuntimeState.ts | 99 ++- packages/chat/src/types/index.ts | 6 - packages/sdk-runtime/package.json | 3 +- packages/sdk-runtime/src/main.ts | 2 +- packages/sdk-runtime/src/runtime.client.ts | 65 -- packages/sdk-runtime/src/sdk/sdk.service.ts | 2 +- .../sdk-runtime/src/trace/trace.service.ts | 9 +- .../src/v2/interact-trace.stream.ts | 23 + packages/sdk-runtime/src/v2/runtime.client.ts | 51 ++ packages/sdk-runtime/src/v2/trace.service.ts | 23 + yarn.lock | 833 ++---------------- 22 files changed, 486 insertions(+), 915 deletions(-) create mode 100644 packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts delete mode 100644 packages/sdk-runtime/src/runtime.client.ts create mode 100644 packages/sdk-runtime/src/v2/interact-trace.stream.ts create mode 100644 packages/sdk-runtime/src/v2/runtime.client.ts create mode 100644 packages/sdk-runtime/src/v2/trace.service.ts diff --git a/apps/documentation/src/components/ChatScript/index.tsx b/apps/documentation/src/components/ChatScript/index.tsx index cd3f5e3398..6f0e8184e8 100644 --- a/apps/documentation/src/components/ChatScript/index.tsx +++ b/apps/documentation/src/components/ChatScript/index.tsx @@ -11,9 +11,9 @@ export const ChatScript = ({ projectID, embedded = false }: { projectID: string; const s = d.getElementsByTagName(t)[0]; v.onload = function () { window.voiceflow.chat.load({ - url: 'https://general-runtime-review-new-widget.us-2.development.voiceflow.com', - verify: { projectID: "${projectID}" }, - assistant: { + url: 'https://general-runtime.voiceflow.com', + verify: { projectID: "${projectID}" }, + assistant: { stylesheet: '../../bundle/style.css', } ${embedded ? ', render: { mode: "embedded", target: document.getElementById("chat_embed") }' : ''} diff --git a/apps/documentation/src/pages/_meta.js b/apps/documentation/src/pages/_meta.js index 0aa0088c6c..138a7571c3 100644 --- a/apps/documentation/src/pages/_meta.js +++ b/apps/documentation/src/pages/_meta.js @@ -6,6 +6,6 @@ export default { title: 'Chat', type: 'page', // eslint-disable-next-line no-secrets/no-secrets - href: '/chat?projectID=672a5d31e7c18363c7363e3f', + href: '/chat?projectID=67646b005e623ff04fdf1f05', }, }; diff --git a/eslint.config.mjs b/eslint.config.mjs index b1802cbd27..045b63cef0 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,6 +1,6 @@ import baseConfig from '@voiceflow/eslint-config'; -/** @type {import('eslint').Linter.FlatConfig[]} */ +/** @type {import('eslint').Linter.Config[]} */ export default [ ...baseConfig, { @@ -10,6 +10,8 @@ export default [ { rules: { 'no-console': ['error', { allow: ['info', 'warn', 'error'] }], + + 'sonarjs/no-one-iteration-loop': 'off', }, }, ]; diff --git a/packages/chat/package.json b/packages/chat/package.json index bab39d02f0..00e1ac8f3c 100644 --- a/packages/chat/package.json +++ b/packages/chat/package.json @@ -75,6 +75,7 @@ "test:unit": "yarn g:vitest run --coverage" }, "dependencies": { + "@paralleldrive/cuid2": "2.2.2", "@vanilla-extract/css": "1.15.5", "@vanilla-extract/recipes": "0.5.5", "@voiceflow/base-types": "2.113.1", @@ -86,6 +87,7 @@ "chroma-js": "2.4.2", "clsx": "1.2.1", "cuid": "2.1.8", + "nanoevents": "9.1.0", "react": "18.2.0", "react-dom": "18.2.0", "react-markdown": "9.0.0", @@ -94,6 +96,7 @@ "react-textarea-autosize": "8.5.3", "regenerator-runtime": "0.13.11", "remark-gfm": "4.0.0", + "remeda": "1.0.1", "slate": "0.94.1", "ts-pattern": "4.3.0", "zod": "3.22.4" diff --git a/packages/chat/src/components/AgentMessage/index.tsx b/packages/chat/src/components/AgentMessage/index.tsx index 972cd4db9c..4aad3fa090 100644 --- a/packages/chat/src/components/AgentMessage/index.tsx +++ b/packages/chat/src/components/AgentMessage/index.tsx @@ -10,6 +10,7 @@ import remarkGfm from 'remark-gfm'; import { FeedbackButton } from '../FeedbackButton'; import { FeedbackButtonVariant, type IFeedbackButton } from '../FeedbackButton/FeedbackButton.interface'; import { Icon } from '../Icon'; +import type { StreamedMessageProps } from '../SystemResponse'; import { agentMessageContainer, aiIconModifier, @@ -126,3 +127,91 @@ export const AgentMessage: React.FC = ({ ); }; + +export const AgentStreamMessage: React.FC & StreamedMessageProps> = ({ + useStream, + children, + ai, + disclaimerMessage = 'Generated by AI, double-check for accuracy.', + isLast, + feedback, + textContent, +}) => { + const text = useStream(); + const content = typeof text === 'string' ? text : serializeToMarkdown(text); + + const isCodeBlock = content?.startsWith('```javascript'); + + return ( +
+ + + + + ) : ( +
+ {children} +
+ ); + }, + li: ({ children, ...props }) => { + // NOTE: this accounts for when the last item in a response is a li and we remove the bottom margin from that. + const position = props.node?.position; + if (position && position.end.offset === text.length - 1) { + return ( +
  • + {children} +
  • + ); + } + return
  • {children}
  • ; + }, + p: ({ children, ...props }) => { + const position = props.node?.position; + const isFirst = position && position.start.offset === 0; + const isLast = position && position.end.offset === text.length - 1; + return ( +

    + {children} +

    + ); + }, + }} + /> + {children &&
    {children}
    } + {ai && ( +
    + + {disclaimerMessage} +
    + )} + {feedback && !isLast && ( +
    + +
    + )} +
    + ); +}; diff --git a/packages/chat/src/components/SystemResponse/SystemMessage.tsx b/packages/chat/src/components/SystemResponse/SystemMessage.tsx index 5b3dd38ea1..793424095b 100644 --- a/packages/chat/src/components/SystemResponse/SystemMessage.tsx +++ b/packages/chat/src/components/SystemResponse/SystemMessage.tsx @@ -100,6 +100,16 @@ export const SystemMessage: React.FC = ({ textContent={textContent} /> )) + .with({ type: MessageType.STREAM }, ({ text, ai }) => ( + + )) .with({ type: MessageType.IMAGE }, ({ url }) => ) .with({ type: MessageType.CARD }, (props) => ) .with({ type: MessageType.EXTENSION }, ({ payload }) => ( diff --git a/packages/chat/src/components/SystemResponse/constants.ts b/packages/chat/src/components/SystemResponse/constants.ts index 35e496fd94..647ae57c04 100644 --- a/packages/chat/src/components/SystemResponse/constants.ts +++ b/packages/chat/src/components/SystemResponse/constants.ts @@ -1,5 +1,6 @@ export enum MessageType { TEXT = 'text', + STREAM = 'stream', IMAGE = 'image', CARD = 'card', CAROUSEL = 'carousel', diff --git a/packages/chat/src/components/SystemResponse/index.tsx b/packages/chat/src/components/SystemResponse/index.tsx index 8cfaf49302..fab456a121 100644 --- a/packages/chat/src/components/SystemResponse/index.tsx +++ b/packages/chat/src/components/SystemResponse/index.tsx @@ -93,12 +93,12 @@ export const SystemResponse: React.FC = ({ }) => { const runtime = useContext(RuntimeStateAPIContext); - const { showIndicator, visibleMessages, complete } = useAnimatedMessages({ - messages, - isLast, - }); + // const { showIndicator, visibleMessages, complete } = useAnimatedMessages({ + // messages, + // isLast, + // }); - useAutoScroll([showIndicator, complete, visibleMessages.length]); + // useAutoScroll([showIndicator, complete, messages.length]); if (!messages.length && !actions.length) return null; @@ -108,9 +108,9 @@ export const SystemResponse: React.FC = ({ } return -1; }; - const lastTextMessageIndex = getLastTextMessageIndex(visibleMessages); + const lastTextMessageIndex = getLastTextMessageIndex(messages); - const allTextContentForMessage = visibleMessages.reduce((acc, message) => { + const allTextContentForMessage = messages.reduce((acc, message) => { if (message.type === MessageType.TEXT) { return ( acc + (acc ? '\n' : '') + (typeof message.text !== 'string' ? serializeToText(message.text) : message.text) @@ -121,34 +121,35 @@ export const SystemResponse: React.FC = ({ return ( - {visibleMessages.map((message, index) => { + {messages.map((message, index) => { const endConversation = message?.type === MessageType.END; if (endConversation) { return ; } - const lastMessageInGroup = index === visibleMessages.length - 1; + // const lastMessageInGroup = index === messages.length - 1; // Showing feedback on previous messages that were in the chat const showFeedback = index === lastTextMessageIndex; // lastMessageInGroup && message.type === MessageType.TEXT; - // Showing feedback on the most recent system message of the chat - const addFeedback = feedback && isLast && complete && lastMessageInGroup; + // // Showing feedback on the most recent system message of the chat + // const addFeedback = feedback && isLast && complete && lastMessageInGroup; return ( <> - {addFeedback && message.type !== MessageType.CAROUSEL && ( + {/* {addFeedback && message.type !== MessageType.CAROUSEL && (
    = ({ variant={FeedbackButtonVariant.LAST_RESPONSE} />
    - )} + )} */} ); })} - {isLast && complete && !!actions.length && ( + {/* {isLast && complete && !!actions.length && (
    {actions.map(({ request, name }, index) => (
    = ({ ))}
    )} - {showIndicator && } + {showIndicator && } */} ); }; diff --git a/packages/chat/src/components/SystemResponse/types.ts b/packages/chat/src/components/SystemResponse/types.ts index faad5a2ee8..0579ceb712 100644 --- a/packages/chat/src/components/SystemResponse/types.ts +++ b/packages/chat/src/components/SystemResponse/types.ts @@ -17,6 +17,15 @@ export interface TextMessageProps extends BaseMessageProps { audio?: { src: string }; } +export interface StreamedMessageProps extends BaseMessageProps { + type: StringifiedEnum; + text: string | Text.SlateTextValue; + + // // a promise that resolves when the stream is finished + // finished: Promise; + useStream: () => string; +} + export interface ImageMessageProps extends BaseMessageProps { type: StringifiedEnum; url: string | null; @@ -50,6 +59,7 @@ export interface CustomMessage extends BaseMessageProps { export type MessageProps = | TextMessageProps + | StreamedMessageProps | ImageMessageProps | CardMessageProps | CarouselMessageProps diff --git a/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts b/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts new file mode 100644 index 0000000000..5330e15d44 --- /dev/null +++ b/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts @@ -0,0 +1,105 @@ +import type { TraceDeclaration } from '@voiceflow/sdk-runtime'; +import { useEffect, useState } from 'react'; +import { match } from 'ts-pattern'; + +import type { StreamedMessageProps } from '@/components/SystemResponse'; + +import type { RuntimeMessage } from '../messages'; + +enum CompletionState { + START = 'start', + CONTENT = 'content', + END = 'end', +} + +interface StartEvent { + state: CompletionState.START; +} + +interface EndEvent { + state: CompletionState.END; +} + +interface ContentEvent { + state: CompletionState.CONTENT; + content: string; +} + +interface CompletionTrace { + type: 'completion'; + payload: StartEvent | EndEvent | ContentEvent; +} + +export const StreamedMessage = (): TraceDeclaration => { + let message: + | (StreamedMessageProps & { + stream: TransformStream; + }) + | null = null; + + return { + canHandle: ({ type }) => type === 'completion', + handle: ({ context }, trace: CompletionTrace) => { + match(trace.payload) + .with({ state: CompletionState.START }, () => { + const stream = new TransformStream(); + + message = { + type: 'stream', + text: '', + stream, + useStream: () => { + const [state, setState] = useState(''); + + useEffect(() => { + try { + const reader = stream.readable.getReader(); + + const read = async () => { + const { done, value } = await reader.read(); + + if (done) return; + + setState((prev) => prev + value); + }; + + read(); + + return () => { + reader.cancel(); + }; + } catch (e) { + console.error('cannot read stream', e); + } + + return undefined; + }, []); + + return state; + }, + }; + context.messages.push(message); + }) + .with({ state: CompletionState.END }, () => { + if (!message) return; + + message.stream.writable.close(); + message = null; + }) + .with({ state: CompletionState.CONTENT }, ({ content }) => { + if (!message) return; + + const writer = message.stream.writable.getWriter(); + writer.write(content); + writer.releaseLock(); + + message.text += content; + + console.log('message', message.text); + }) + .exhaustive(); + + return context; + }, + }; +}; diff --git a/packages/chat/src/contexts/RuntimeContext/useRuntimeAPI.ts b/packages/chat/src/contexts/RuntimeContext/useRuntimeAPI.ts index 65036596a0..d41f24637a 100644 --- a/packages/chat/src/contexts/RuntimeContext/useRuntimeAPI.ts +++ b/packages/chat/src/contexts/RuntimeContext/useRuntimeAPI.ts @@ -1,5 +1,5 @@ import type { RuntimeAction } from '@voiceflow/sdk-runtime'; -import { VoiceflowRuntime } from '@voiceflow/sdk-runtime'; +import { RuntimeClient, VoiceflowRuntime } from '@voiceflow/sdk-runtime'; import { serializeToText } from '@voiceflow/slate-serializer/text'; import { useMemo } from 'react'; @@ -29,6 +29,14 @@ export const useRuntimeAPI = ({ versionID, traceHandlers = [], }: ChatConfig & Pick & { traceHandlers?: typeof MESSAGE_TRACES }) => { + const client: RuntimeClient = useMemo( + () => + new RuntimeClient({ + baseURL: url, + traces: [...MESSAGE_TRACES, ...traceHandlers], + }), + [] + ); const runtime: VoiceflowRuntime = useMemo( () => new VoiceflowRuntime({ @@ -47,6 +55,14 @@ export const useRuntimeAPI = ({ ...(versionID && { versionID }), }); + const interactStream = (action: RuntimeAction) => + client.interactStream(createContext, { + userID, + action, + projectID: verify.projectID, + ...(versionID && { environment: versionID }), + }); + const saveFeedback = async (name: FeedbackName, lastTurnMessages: MessageProps[], userTurn: UserTurnProps | null) => { const aiMessages: string[] = []; @@ -82,5 +98,5 @@ export const useRuntimeAPI = ({ }); }; - return { interact, saveFeedback, saveTranscript }; + return { interact, interactStream, saveFeedback, saveTranscript }; }; diff --git a/packages/chat/src/contexts/RuntimeContext/useRuntimeState.ts b/packages/chat/src/contexts/RuntimeContext/useRuntimeState.ts index e57c24fe2a..126ca3a299 100644 --- a/packages/chat/src/contexts/RuntimeContext/useRuntimeState.ts +++ b/packages/chat/src/contexts/RuntimeContext/useRuntimeState.ts @@ -1,15 +1,21 @@ +import { createId } from '@paralleldrive/cuid2'; import type { BaseRequest } from '@voiceflow/dtos-interact'; import { isTextRequest, RequestType } from '@voiceflow/dtos-interact'; import type { TraceDeclaration } from '@voiceflow/sdk-runtime'; -import cuid from 'cuid'; import { useEffect, useRef, useState } from 'react'; -import { DEFAULT_MESSAGE_DELAY, MessageType } from '@/components/SystemResponse/constants'; import { isIOS } from '@/device'; import type { ChatConfig } from '@/dtos/ChatConfig.dto'; import { useStateRef } from '@/hooks/useStateRef'; import { useLocalStorageState } from '@/hooks/useStorage'; -import type { ChatPersistence, ChatWidgetSettings, SendMessage, SessionOptions, TurnProps } from '@/types'; +import type { + ChatPersistence, + ChatWidgetSettings, + SendMessage, + SessionOptions, + SystemTurnProps, + TurnProps, +} from '@/types'; import { SessionStatus, TurnType } from '@/types'; import { handleActions } from '@/utils/actions'; import { broadcast, BroadcastType } from '@/utils/broadcast'; @@ -22,8 +28,9 @@ import { silentAudio } from './silent-audio'; import { EffectExtensions } from './traces/EffectExtensions.trace'; import { NoReply } from './traces/NoReply.trace'; import { ResponseExtensions } from './traces/ResponseExtensions.trace'; +import { StreamedMessage } from './traces/StreamedMessage.trace'; import { useNoReply } from './useNoReply'; -import { createContext, useRuntimeAPI } from './useRuntimeAPI'; +import { useRuntimeAPI } from './useRuntimeAPI'; export interface Settings { assistant: ChatWidgetSettings; @@ -50,7 +57,7 @@ export const useRuntimeState = ({ assistant, config, traceHandlers }: Settings) status: config.autostart ? SessionStatus.IDLE : SessionStatus.ENDED, // retrieve stored session ...getSession(assistant.common.persistence as ChatPersistence, config.verify.projectID, config.userID), - ...{ userID: config.userID || cuid() }, + ...{ userID: config.userID || createId() }, })); const [indicator, setIndicator] = useState(false); @@ -60,6 +67,7 @@ export const useRuntimeState = ({ assistant, config, traceHandlers }: Settings) ...config, ...session, traceHandlers: [ + StreamedMessage(), NoReply(setNoReplyTimeout), ...EffectExtensions(assistant.extensions), ...ResponseExtensions(assistant.extensions), @@ -84,6 +92,30 @@ export const useRuntimeState = ({ assistant, config, traceHandlers }: Settings) const addTurn = (turn: TurnProps) => setTurns((prev) => [...prev, turn]); + const updateTurn = (turnID: string, data: RuntimeMessage) => + setTurns((prev) => { + if (!prev.length) return prev; + + const turn = [...prev] + .reverse() + .find((turn): turn is SystemTurnProps => turn.id === turnID && turn.type === TurnType.SYSTEM); + if (!turn) return prev; + + const turnIndex = prev.indexOf(turn); + const cloned = [...prev]; + + cloned.splice(turnIndex, 1, { + ...turn, + messages: [...turn.messages, ...data.messages], + actions: data.actions ?? turn.actions, + }); + + console.log('updated', cloned); + console.log('data', data); + + return cloned; + }); + const reset = () => setTurns(() => []); const interact: SendMessage = async (action: BaseRequest, message?: string) => { @@ -99,7 +131,7 @@ export const useRuntimeState = ({ assistant, config, traceHandlers }: Settings) const userMessage = message || (isTextRequest(action) ? action.payload : null); if (userMessage) { addTurn({ - id: cuid(), + id: createId(), type: TurnType.USER, message: userMessage, timestamp: Date.now(), @@ -109,36 +141,49 @@ export const useRuntimeState = ({ assistant, config, traceHandlers }: Settings) const userAction = resolveAction(action, getTurns()); setIndicator(true); - const context = await runtime.interact(userAction, { tts: isAudioOutputEnabled() }).catch((error) => { + const stream = await runtime.interactStream(userAction).catch((error) => { // TODO: better define error condition console.error(error); - return createContext(); + return new ReadableStream(); }); setIndicator(false); + const turnID = createId(); + addTurn({ - id: cuid(), + id: turnID, type: TurnType.SYSTEM, timestamp: Date.now(), - ...context, + messages: [], }); - const shouldPlay = isAudioOutputEnabled() && playAudiosStack.current.length === 0; + const reader = stream.getReader(); - if (isAudioOutputEnabled()) { - context.messages.forEach((message) => { - if (message.type === MessageType.TEXT && message.audio?.src) { - playAudiosStack.current.push(message.audio.src); - } - }); + // eslint-disable-next-line no-constant-condition + while (true) { + // eslint-disable-next-line no-await-in-loop + const { done, value } = await reader.read(); + if (done) break; + + updateTurn(turnID, value); } - if (shouldPlay) { - // eslint-disable-next-line no-promise-executor-return - await new Promise((resolve) => setTimeout(resolve, DEFAULT_MESSAGE_DELAY)); + // const shouldPlay = isAudioOutputEnabled() && playAudiosStack.current.length === 0; - playAudioCircle(); - } + // if (isAudioOutputEnabled()) { + // stream.messages.forEach((message) => { + // if (message.type === MessageType.TEXT && message.audio?.src) { + // playAudiosStack.current.push(message.audio.src); + // } + // }); + // } + + // if (shouldPlay) { + // // eslint-disable-next-line no-promise-executor-return + // await new Promise((resolve) => setTimeout(resolve, DEFAULT_MESSAGE_DELAY)); + + // playAudioCircle(); + // } broadcast({ type: BroadcastType.INTERACT, payload: { session: sessionRef.current, action: userAction } }); saveSession(assistant.common.persistence as ChatPersistence, config.verify.projectID, sessionRef.current); @@ -192,13 +237,13 @@ export const useRuntimeState = ({ assistant, config, traceHandlers }: Settings) audio.stop(); }; - const playAudioCircle = async () => { - if (!isAudioOutputEnabled() || !playAudiosStack.current.length) return; + // const playAudioCircle = async () => { + // if (!isAudioOutputEnabled() || !playAudiosStack.current.length) return; - await audio.play(playAudiosStack.current.shift()); + // await audio.play(playAudiosStack.current.shift()); - playAudioCircle(); - }; + // playAudioCircle(); + // }; const toggleAudioOutput = () => { stopAudios(); diff --git a/packages/chat/src/types/index.ts b/packages/chat/src/types/index.ts index 26e6175b15..ddacb6c4f7 100644 --- a/packages/chat/src/types/index.ts +++ b/packages/chat/src/types/index.ts @@ -1,4 +1,3 @@ -import type { $$StyledComponentProps } from '@voiceflow/stitches-react/types/styled-component'; export * from './session'; export * from './settings'; export * from './trace'; @@ -8,8 +7,3 @@ export * from './variants'; export { ChatPersistence, ChatPosition } from '@voiceflow/voiceflow-types/build/cjs/version/chat'; export type Nullish = T | null | undefined; - -export type VariantProp< - Component extends { [key: symbol | string]: any }, - Key extends keyof Component[$$StyledComponentProps], -> = Component[$$StyledComponentProps][Key]; diff --git a/packages/sdk-runtime/package.json b/packages/sdk-runtime/package.json index 4916daf78c..89c8a092ab 100644 --- a/packages/sdk-runtime/package.json +++ b/packages/sdk-runtime/package.json @@ -30,7 +30,8 @@ "http-errors": "2.0.0" }, "devDependencies": { - "@types/http-errors": "^1.8.2" + "@types/http-errors": "^1.8.2", + "eventsource-parser": "3.0.0" }, "volta": { "extends": "../../package.json" diff --git a/packages/sdk-runtime/src/main.ts b/packages/sdk-runtime/src/main.ts index b4750c8235..a3c573cb73 100644 --- a/packages/sdk-runtime/src/main.ts +++ b/packages/sdk-runtime/src/main.ts @@ -1,4 +1,4 @@ export * from './runtime'; -export * from './runtime.client'; export * from './sdk'; export * from './trace'; +export * from './v2/runtime.client'; diff --git a/packages/sdk-runtime/src/runtime.client.ts b/packages/sdk-runtime/src/runtime.client.ts deleted file mode 100644 index 71316cc45b..0000000000 --- a/packages/sdk-runtime/src/runtime.client.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type { Trace } from '@voiceflow/base-types'; -import { FetchClient } from '@voiceflow/fetch'; -import { createParser, type EventSourceMessage } from 'eventsource-parser'; - -import type { RuntimeAction } from './runtime'; - -export interface RuntimeClientOptions { - baseURL: string; -} - -export interface InteractStreamRequest { - projectID: string; - userID: string; - environment?: string; - - action: RuntimeAction; -} - -export class RuntimeClient { - private readonly fetch = new FetchClient({ baseURL: this.options.baseURL }); - - constructor(private readonly options: RuntimeClientOptions) {} - - async interactStream({ projectID, userID, environment, action }: InteractStreamRequest) { - const result = await this.fetch.post( - `/v2/public/project/${projectID}/user/${encodeURIComponent(userID)}/interact/stream`, - { - query: new URLSearchParams({ - completion_events: String(true), - ...(environment && { environment }), - }), - json: { action }, - } - ); - - if (!result.body) { - throw new Error('interact stream body is empty'); - } - - const traces = new WritableStream(); - const parser = createParser({ - onEvent: (event: EventSourceMessage) => { - traces.getWriter().write(JSON.parse(event.data)); - }, - }); - const decoder = new TextDecoder(); - - const process = async () => { - for await (const chunk of result.body!) { - const text = decoder.decode(chunk, { stream: true }); - - parser.feed(text); - } - - await traces.close(); - }; - - process().catch(async (err) => { - console.error(err); - await traces.abort(); - }); - - return traces; - } -} diff --git a/packages/sdk-runtime/src/sdk/sdk.service.ts b/packages/sdk-runtime/src/sdk/sdk.service.ts index 9a039b3a4f..89e6d6f3e6 100644 --- a/packages/sdk-runtime/src/sdk/sdk.service.ts +++ b/packages/sdk-runtime/src/sdk/sdk.service.ts @@ -38,7 +38,7 @@ export class VoiceflowRuntime { public async interact(context: T, request: RuntimeInteractRequest): Promise { const response = await this.runtime.interact(request); - return this.trace.processTrace(context, response); + return this.trace.processResponse(context, response); } public async feedback(request: RuntimeFeedbackRequest) { diff --git a/packages/sdk-runtime/src/trace/trace.service.ts b/packages/sdk-runtime/src/trace/trace.service.ts index 1eb510f863..5fa9276581 100644 --- a/packages/sdk-runtime/src/trace/trace.service.ts +++ b/packages/sdk-runtime/src/trace/trace.service.ts @@ -6,7 +6,7 @@ export class TraceService { private readonly traces: TraceDeclaration[] = []; public constructor(options: TraceOptions = {}) { - this.registerTraces(options.traces ?? []); + this.traces = options.traces ?? []; } public registerTrace(step: TraceDeclaration): this { @@ -14,12 +14,7 @@ export class TraceService { return this; } - public registerTraces(steps: TraceDeclaration[]): this { - steps.forEach((step) => this.registerTrace(step)); - return this; - } - - public async processTrace(context: T, response: Pick): Promise { + public async processResponse(context: T, response: Pick): Promise { const meta: TraceHandlerMeta = { context }; for (const trace of response.trace) { diff --git a/packages/sdk-runtime/src/v2/interact-trace.stream.ts b/packages/sdk-runtime/src/v2/interact-trace.stream.ts new file mode 100644 index 0000000000..9f75322465 --- /dev/null +++ b/packages/sdk-runtime/src/v2/interact-trace.stream.ts @@ -0,0 +1,23 @@ +import type { EventSourceMessage } from 'eventsource-parser'; + +import type { TraceService } from './trace.service'; + +export class InteractTraceStream extends TransformStream { + constructor( + private readonly createContext: () => T, + private readonly trace: TraceService + ) { + super({ + // start: () => {}, + // flush: () => {}, + + transform: async (chunk, controller) => { + const data = JSON.parse(chunk.data); + const trace = await this.trace.processTrace(this.createContext(), data); + if (!trace) return; + + controller.enqueue(trace); + }, + }); + } +} diff --git a/packages/sdk-runtime/src/v2/runtime.client.ts b/packages/sdk-runtime/src/v2/runtime.client.ts new file mode 100644 index 0000000000..8843bfe253 --- /dev/null +++ b/packages/sdk-runtime/src/v2/runtime.client.ts @@ -0,0 +1,51 @@ +import { FetchClient } from '@voiceflow/fetch'; +import { EventSourceParserStream } from 'eventsource-parser/stream'; + +import type { RuntimeAction } from '@/runtime'; +import type { TraceOptions } from '@/trace'; + +import { InteractTraceStream } from './interact-trace.stream'; +import { TraceService } from './trace.service'; + +export interface RuntimeClientOptions extends TraceOptions { + baseURL: string; +} + +export interface InteractStreamRequest { + projectID: string; + userID: string; + environment?: string; + + action: RuntimeAction; +} + +export class RuntimeClient { + private readonly fetch = new FetchClient({ baseURL: this.options.baseURL }); + + constructor( + private readonly options: RuntimeClientOptions, + private readonly trace = new TraceService({ traces: options.traces }) + ) {} + + async interactStream(createContext: () => T, { projectID, userID, environment, action }: InteractStreamRequest) { + const result = await this.fetch.post( + `/v2/public/project/${projectID}/user/${encodeURIComponent(userID)}/interact/stream`, + { + query: new URLSearchParams({ + completion_events: String(true), + ...(environment && { environment }), + }), + json: { action }, + } + ); + + if (!result.body) { + throw new Error('interact stream body is empty'); + } + + return result.body + .pipeThrough(new TextDecoderStream()) + .pipeThrough(new EventSourceParserStream()) + .pipeThrough(new InteractTraceStream(createContext, this.trace)); + } +} diff --git a/packages/sdk-runtime/src/v2/trace.service.ts b/packages/sdk-runtime/src/v2/trace.service.ts new file mode 100644 index 0000000000..c598d75fb8 --- /dev/null +++ b/packages/sdk-runtime/src/v2/trace.service.ts @@ -0,0 +1,23 @@ +import { Trace } from '@voiceflow/base-types'; + +import type { TraceDeclaration, TraceOptions } from '@/trace'; + +export class TraceService { + private readonly traces: TraceDeclaration[] = []; + + public constructor(options: TraceOptions = {}) { + this.traces = options.traces ?? []; + } + + public registerTrace(step: TraceDeclaration): this { + this.traces.push(step); + return this; + } + + public async processTrace(context: T, data: Trace.AnyTrace): Promise { + const trace = this.traces.find((trace) => trace.canHandle(data)); + if (!trace) return null; + + return trace.handle({ context }, data); + } +} diff --git a/yarn.lock b/yarn.lock index 0558fdaf7b..fa8255fd95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2612,13 +2612,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/aix-ppc64@npm:0.19.12" - conditions: os=aix & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/aix-ppc64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/aix-ppc64@npm:0.20.2" @@ -2647,13 +2640,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm64@npm:0.19.12" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/android-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/android-arm64@npm:0.20.2" @@ -2682,13 +2668,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm@npm:0.19.12" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@esbuild/android-arm@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/android-arm@npm:0.20.2" @@ -2717,13 +2696,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-x64@npm:0.19.12" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - "@esbuild/android-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/android-x64@npm:0.20.2" @@ -2752,13 +2724,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-arm64@npm:0.19.12" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/darwin-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/darwin-arm64@npm:0.20.2" @@ -2787,13 +2752,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-x64@npm:0.19.12" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "@esbuild/darwin-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/darwin-x64@npm:0.20.2" @@ -2822,13 +2780,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-arm64@npm:0.19.12" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/freebsd-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/freebsd-arm64@npm:0.20.2" @@ -2857,13 +2808,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-x64@npm:0.19.12" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/freebsd-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/freebsd-x64@npm:0.20.2" @@ -2892,13 +2836,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm64@npm:0.19.12" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/linux-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-arm64@npm:0.20.2" @@ -2927,13 +2864,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm@npm:0.19.12" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "@esbuild/linux-arm@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-arm@npm:0.20.2" @@ -2962,13 +2892,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ia32@npm:0.19.12" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/linux-ia32@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-ia32@npm:0.20.2" @@ -2997,13 +2920,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-loong64@npm:0.19.12" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - "@esbuild/linux-loong64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-loong64@npm:0.20.2" @@ -3032,13 +2948,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-mips64el@npm:0.19.12" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - "@esbuild/linux-mips64el@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-mips64el@npm:0.20.2" @@ -3067,13 +2976,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ppc64@npm:0.19.12" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/linux-ppc64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-ppc64@npm:0.20.2" @@ -3102,13 +3004,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-riscv64@npm:0.19.12" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - "@esbuild/linux-riscv64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-riscv64@npm:0.20.2" @@ -3137,13 +3032,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-s390x@npm:0.19.12" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - "@esbuild/linux-s390x@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-s390x@npm:0.20.2" @@ -3172,13 +3060,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-x64@npm:0.19.12" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - "@esbuild/linux-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/linux-x64@npm:0.20.2" @@ -3207,13 +3088,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/netbsd-x64@npm:0.19.12" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/netbsd-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/netbsd-x64@npm:0.20.2" @@ -3249,13 +3123,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/openbsd-x64@npm:0.19.12" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/openbsd-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/openbsd-x64@npm:0.20.2" @@ -3284,13 +3151,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/sunos-x64@npm:0.19.12" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - "@esbuild/sunos-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/sunos-x64@npm:0.20.2" @@ -3319,13 +3179,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-arm64@npm:0.19.12" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/win32-arm64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/win32-arm64@npm:0.20.2" @@ -3354,13 +3207,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-ia32@npm:0.19.12" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/win32-ia32@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/win32-ia32@npm:0.20.2" @@ -3389,13 +3235,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-x64@npm:0.19.12" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@esbuild/win32-x64@npm:0.20.2": version: 0.20.2 resolution: "@esbuild/win32-x64@npm:0.20.2" @@ -4098,6 +3937,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:^1.1.5": + version: 1.6.1 + resolution: "@noble/hashes@npm:1.6.1" + checksum: 57c62f65ee217c0293b4321b547792aa6d79812bfe70a7d62dc83e0f936cc677b14ed981b4e88cf8fdad37cd6d3a0cbd3bd0908b0728adc9daf066e678be8901 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -4180,6 +4026,15 @@ __metadata: languageName: node linkType: hard +"@paralleldrive/cuid2@npm:2.2.2": + version: 2.2.2 + resolution: "@paralleldrive/cuid2@npm:2.2.2" + dependencies: + "@noble/hashes": ^1.1.5 + checksum: f7f6ac70e0268ec2c72e555719240d5c2c9a859ce541ac1c637eed3f3ee971b42881d299dedafbded53e7365b9e98176c5a31c442c1112f7e9e7306f2fd0ecbb + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -6105,15 +5960,6 @@ __metadata: languageName: node linkType: hard -"@types/cors@npm:2.8.13": - version: 2.8.13 - resolution: "@types/cors@npm:2.8.13" - dependencies: - "@types/node": "*" - checksum: 7ef197ea19d2e5bf1313b8416baa6f3fd6dd887fd70191da1f804f557395357dafd8bc8bed0ac60686923406489262a7c8a525b55748f7b2b8afa686700de907 - languageName: node - linkType: hard - "@types/cross-spawn@npm:^6.0.2": version: 6.0.6 resolution: "@types/cross-spawn@npm:6.0.6" @@ -6225,7 +6071,7 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33": +"@types/express-serve-static-core@npm:^4.17.33": version: 4.17.43 resolution: "@types/express-serve-static-core@npm:4.17.43" dependencies: @@ -6237,18 +6083,7 @@ __metadata: languageName: node linkType: hard -"@types/express-ws@npm:3.0.1": - version: 3.0.1 - resolution: "@types/express-ws@npm:3.0.1" - dependencies: - "@types/express": "*" - "@types/express-serve-static-core": "*" - "@types/ws": "*" - checksum: fe0979f0c4ae6ce1d3cd6e9e5a99882d7dd461a774b3ad67066965db058bc9cc90ec9deed6bb4ee8414cf50b800ab84d6d042d375ee3b0b31483a3ec91647146 - languageName: node - linkType: hard - -"@types/express@npm:*, @types/express@npm:^4.7.0": +"@types/express@npm:^4.7.0": version: 4.17.21 resolution: "@types/express@npm:4.17.21" dependencies: @@ -6260,18 +6095,6 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:4.17.17": - version: 4.17.17 - resolution: "@types/express@npm:4.17.17" - dependencies: - "@types/body-parser": "*" - "@types/express-serve-static-core": ^4.17.33 - "@types/qs": "*" - "@types/serve-static": "*" - checksum: 0196dacc275ac3ce89d7364885cb08e7fb61f53ca101f65886dbf1daf9b7eb05c0943e2e4bbd01b0cc5e50f37e0eea7e4cbe97d0304094411ac73e1b7998f4da - languageName: node - linkType: hard - "@types/find-cache-dir@npm:^3.2.1": version: 3.2.1 resolution: "@types/find-cache-dir@npm:3.2.1" @@ -6379,15 +6202,6 @@ __metadata: languageName: node linkType: hard -"@types/lodash-es@npm:^4.17.8": - version: 4.17.12 - resolution: "@types/lodash-es@npm:4.17.12" - dependencies: - "@types/lodash": "*" - checksum: 990a99e2243bebe9505cb5ad19fbc172beb4a8e00f9075c99fc06c46c2801ffdb40bc2867271cf580d5f48994fc9fb076ec92cd60a20e621603bf22114e5b077 - languageName: node - linkType: hard - "@types/lodash.memoize@npm:^4.1.7": version: 4.1.9 resolution: "@types/lodash.memoize@npm:4.1.9" @@ -6723,24 +6537,6 @@ __metadata: languageName: node linkType: hard -"@types/ws@npm:*": - version: 8.5.10 - resolution: "@types/ws@npm:8.5.10" - dependencies: - "@types/node": "*" - checksum: 3ec416ea2be24042ebd677932a462cf16d2080393d8d7d0b1b3f5d6eaa4a7387aaf0eefb99193c0bfd29444857cf2e0c3ac89899e130550dc6c14ada8a46d25e - languageName: node - linkType: hard - -"@types/ws@npm:8.5.11": - version: 8.5.11 - resolution: "@types/ws@npm:8.5.11" - dependencies: - "@types/node": "*" - checksum: 91d3ad6cc802f52b01c8cc7b0de149617785e8166e631291201d5f50937db2a578cbe70b61d96f43140d57170ad2f904782d3ec9ed86c34c5e9cec9a847a94dc - languageName: node - linkType: hard - "@typescript-eslint/eslint-plugin@npm:7.6.0": version: 7.6.0 resolution: "@typescript-eslint/eslint-plugin@npm:7.6.0" @@ -7038,7 +6834,7 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.0.0, @ungap/structured-clone@npm:^1.2.0": +"@ungap/structured-clone@npm:^1.0.0": version: 1.2.0 resolution: "@ungap/structured-clone@npm:1.2.0" checksum: 4f656b7b4672f2ce6e272f2427d8b0824ed11546a601d8d5412b9d7704e83db38a8d9f402ecdf2b9063fc164af842ad0ec4a55819f621ed7e7ea4d1efcc74524 @@ -7350,48 +7146,6 @@ __metadata: languageName: node linkType: hard -"@voiceflow-example/live-agent-server@workspace:examples/live-agent/server": - version: 0.0.0-use.local - resolution: "@voiceflow-example/live-agent-server@workspace:examples/live-agent/server" - dependencies: - "@types/cors": 2.8.13 - "@types/express": 4.17.17 - "@types/express-ws": 3.0.1 - "@types/ws": 8.5.11 - body-parser: 1.20.2 - cors: 2.8.5 - dotenv: 16.3.1 - express: 4.19.2 - express-ws: 5.0.2 - intercom-client: 5.0.0 - string-strip-html: 13.4.2 - ts-pattern: 4.3.0 - tsx: 4.7.2 - ws: 8.18.0 - languageName: unknown - linkType: soft - -"@voiceflow-example/live-agent@workspace:examples/live-agent": - version: 0.0.0-use.local - resolution: "@voiceflow-example/live-agent@workspace:examples/live-agent" - dependencies: - "@types/node": 20.12.7 - "@types/react": 18.2.8 - "@types/react-dom": 18.2.4 - "@voiceflow/exception": 1.4.0 - "@voiceflow/fetch": 1.5.2 - "@voiceflow/react-chat-legacy": "workspace:*" - "@voiceflow/slate-serializer": 1.4.2 - nanoevents: 8.0.0 - react: 18.2.0 - react-calendar: 4.3.0 - react-dom: 18.2.0 - styled-components: 6.0.3 - ts-pattern: 4.3.0 - vite: 4.3.9 - languageName: unknown - linkType: soft - "@voiceflow-example/live-chat@workspace:examples/live-chat": version: 0.0.0-use.local resolution: "@voiceflow-example/live-chat@workspace:examples/live-chat" @@ -7471,15 +7225,6 @@ __metadata: languageName: node linkType: hard -"@voiceflow/dtos-interact@npm:1.1.0": - version: 1.1.0 - resolution: "@voiceflow/dtos-interact@npm:1.1.0" - peerDependencies: - zod: ^3 - checksum: 8bee2582c79254c5a227fadd7f68c6484e72cdb5f7f8339272a453422740d937dbc37632cc29358980eb1a9a33a7ad491369f732949b87c03d3c9ad1e4ac1f1e - languageName: node - linkType: hard - "@voiceflow/dtos-interact@npm:1.10.0": version: 1.10.0 resolution: "@voiceflow/dtos-interact@npm:1.10.0" @@ -7553,80 +7298,6 @@ __metadata: languageName: node linkType: hard -"@voiceflow/react-chat-legacy@workspace:*, @voiceflow/react-chat-legacy@workspace:packages/react-chat": - version: 0.0.0-use.local - resolution: "@voiceflow/react-chat-legacy@workspace:packages/react-chat" - dependencies: - "@babel/core": 7.18.10 - "@babel/preset-env": 7.24.1 - "@babel/preset-react": 7.24.1 - "@babel/preset-typescript": 7.24.1 - "@emotion/core": 10.1.1 - "@playwright/test": 1.43.1 - "@storybook/addon-actions": 8.0.2 - "@storybook/addon-essentials": 8.0.2 - "@storybook/addon-interactions": 8.0.2 - "@storybook/addon-links": 8.0.2 - "@storybook/builder-vite": 8.0.2 - "@storybook/eslint-config-storybook": 3.1.2 - "@storybook/react": 8.0.2 - "@storybook/react-vite": 8.0.2 - "@storybook/testing-library": 0.0.13 - "@testing-library/jest-dom": 6.4.2 - "@testing-library/react": 15.0.2 - "@types/chroma-js": 2.1.4 - "@types/node": 20.12.7 - "@types/react": 18.2.8 - "@types/react-dom": 18.2.4 - "@types/react-speech-recognition": ^3.9.5 - "@vitejs/plugin-react": 4.2.1 - "@voiceflow/base-types": 2.113.1 - "@voiceflow/dtos-interact": 1.1.0 - "@voiceflow/sdk-runtime": "workspace:*" - "@voiceflow/slate-serializer": 1.5.5 - "@voiceflow/stitches-react": 2.3.1 - "@voiceflow/test-common": 1.10.3 - "@voiceflow/voiceflow-types": 3.32.1 - bowser: 2.11.0 - chroma-js: 2.4.2 - chromatic: 11.2.0 - clsx: 1.2.1 - csstype: 3.1.0 - cuid: 2.1.8 - dayjs: 1.11.5 - eslint-plugin-mdx: 3.1.5 - eslint-plugin-storybook: 0.8.0 - happy-dom: 14.7.1 - http-server: 14.1.1 - react: 18.2.0 - react-dom: 18.2.0 - react-markdown: 9.0.0 - react-speech-recognition: 3.10.0 - react-textarea-autosize: 8.5.3 - regenerator-runtime: 0.13.11 - rehype-raw: 7.0.0 - rehype-sanitize: 6.0.0 - remark-gfm: 4.0.0 - remeda: 1.0.1 - slate: 0.94.1 - storybook: 8.0.2 - storybook-dark-mode: 1.1.0 - ts-pattern: 4.3.0 - tsc-alias: 1.8.8 - type-fest: 2.18.1 - vite: 5.2.9 - vite-plugin-dts: 3.8.3 - vite-plugin-fonts: 0.7.0 - vite-plugin-html: 3.2.2 - vite-plugin-svgr: 4.2.0 - vite-tsconfig-paths: 4.3.2 - zod: 3.22.4 - peerDependencies: - react: ^18 - react-dom: ^18 - languageName: unknown - linkType: soft - "@voiceflow/react-chat@workspace:*, @voiceflow/react-chat@workspace:packages/chat": version: 0.0.0-use.local resolution: "@voiceflow/react-chat@workspace:packages/chat" @@ -7636,6 +7307,7 @@ __metadata: "@babel/preset-react": 7.24.1 "@babel/preset-typescript": 7.24.1 "@emotion/core": 10.1.1 + "@paralleldrive/cuid2": 2.2.2 "@playwright/test": 1.43.1 "@storybook/addon-actions": 8.0.2 "@storybook/addon-essentials": 8.0.2 @@ -7674,6 +7346,7 @@ __metadata: eslint-plugin-storybook: 0.8.0 happy-dom: 14.7.1 http-server: 14.1.1 + nanoevents: 9.1.0 react: 18.2.0 react-dom: 18.2.0 react-markdown: 9.0.0 @@ -7682,6 +7355,7 @@ __metadata: react-textarea-autosize: 8.5.3 regenerator-runtime: 0.13.11 remark-gfm: 4.0.0 + remeda: 1.0.1 slate: 0.94.1 storybook: 8.0.2 storybook-dark-mode: 1.1.0 @@ -7708,6 +7382,7 @@ __metadata: dependencies: "@types/http-errors": ^1.8.2 "@voiceflow/base-types": 2.113.1 + eventsource-parser: 3.0.0 http-errors: 2.0.0 languageName: unknown linkType: soft @@ -7738,15 +7413,6 @@ __metadata: languageName: node linkType: hard -"@voiceflow/stitches-react@npm:2.3.1": - version: 2.3.1 - resolution: "@voiceflow/stitches-react@npm:2.3.1" - peerDependencies: - react: ">= 16.3.0" - checksum: b141c538947a8a7845b1e3782cf4a2ba3bfcabf98e0d408d9fec033516aaf5b800466fe451f9cc44123f666cd147069f4e1ee336feea6806883a3c8efc0ecee8 - languageName: node - linkType: hard - "@voiceflow/test-common@npm:1.10.3": version: 1.10.3 resolution: "@voiceflow/test-common@npm:1.10.3" @@ -8488,13 +8154,6 @@ __metadata: languageName: node linkType: hard -"asynckit@npm:^0.4.0": - version: 0.4.0 - resolution: "asynckit@npm:0.4.0" - checksum: 7b78c451df768adba04e2d02e63e2d0bf3b07adcd6e42b4cf665cb7ce899bedd344c69a1dcbce355b5f972d597b25aaa1c1742b52cffd9caccb22f348114f6be - languageName: node - linkType: hard - "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -8511,17 +8170,6 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.6.0": - version: 1.7.2 - resolution: "axios@npm:1.7.2" - dependencies: - follow-redirects: ^1.15.6 - form-data: ^4.0.0 - proxy-from-env: ^1.1.0 - checksum: e457e2b0ab748504621f6fa6609074ac08c824bf0881592209dfa15098ece7e88495300e02cd22ba50b3468fd712fe687e629dcb03d6a3f6a51989727405aedf - languageName: node - linkType: hard - "axobject-query@npm:^2.2.0": version: 2.2.0 resolution: "axobject-query@npm:2.2.0" @@ -9400,15 +9048,6 @@ __metadata: languageName: node linkType: hard -"codsen-utils@npm:^1.6.1, codsen-utils@npm:^1.6.4": - version: 1.6.4 - resolution: "codsen-utils@npm:1.6.4" - dependencies: - rfdc: ^1.3.1 - checksum: 22087cd2772ee91583222150f99b1eb145da491b57a4cce80acd042a354513ffc85384b7525d3ebde49e6b5b325e8943eebf170e60bc0901cd8a21689a4f1b1a - languageName: node - linkType: hard - "collapse-white-space@npm:^1.0.4": version: 1.0.6 resolution: "collapse-white-space@npm:1.0.6" @@ -9478,15 +9117,6 @@ __metadata: languageName: node linkType: hard -"combined-stream@npm:^1.0.8": - version: 1.0.8 - resolution: "combined-stream@npm:1.0.8" - dependencies: - delayed-stream: ~1.0.0 - checksum: 49fa4aeb4916567e33ea81d088f6584749fc90c7abec76fd516bf1c5aa5c79f3584b5ba3de6b86d26ddd64bae5329c4c7479343250cfe71c75bb366eae53bb7c - languageName: node - linkType: hard - "comma-separated-tokens@npm:^1.0.0": version: 1.0.8 resolution: "comma-separated-tokens@npm:1.0.8" @@ -9772,13 +9402,6 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.6.0": - version: 0.6.0 - resolution: "cookie@npm:0.6.0" - checksum: f56a7d32a07db5458e79c726b77e3c2eff655c36792f2b6c58d351fb5f61531e5b1ab7f46987150136e366c65213cbe31729e02a3eaed630c3bf7334635fb410 - languageName: node - linkType: hard - "core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.36.0, core-js-compat@npm:^3.36.1": version: 3.36.1 resolution: "core-js-compat@npm:3.36.1" @@ -9818,16 +9441,6 @@ __metadata: languageName: node linkType: hard -"cors@npm:2.8.5": - version: 2.8.5 - resolution: "cors@npm:2.8.5" - dependencies: - object-assign: ^4 - vary: ^1 - checksum: ced838404ccd184f61ab4fdc5847035b681c90db7ac17e428f3d81d69e2989d2b680cc254da0e2554f5ed4f8a341820a1ce3d1c16b499f6e2f47a1b9b07b5006 - languageName: node - linkType: hard - "corser@npm:^2.0.1": version: 2.0.1 resolution: "corser@npm:2.0.1" @@ -10016,13 +9629,6 @@ __metadata: languageName: node linkType: hard -"csstype@npm:3.1.0, csstype@npm:^3.0.2": - version: 3.1.0 - resolution: "csstype@npm:3.1.0" - checksum: 644e986cefab86525f0b674a06889cfdbb1f117e5b7d1ce0fc55b0423ecc58807a1ea42ecc75c4f18999d14fc42d1d255f84662a45003a52bb5840e977eb2ffd - languageName: node - linkType: hard - "csstype@npm:3.1.2": version: 3.1.2 resolution: "csstype@npm:3.1.2" @@ -10037,6 +9643,13 @@ __metadata: languageName: node linkType: hard +"csstype@npm:^3.0.2": + version: 3.1.0 + resolution: "csstype@npm:3.1.0" + checksum: 644e986cefab86525f0b674a06889cfdbb1f117e5b7d1ce0fc55b0423ecc58807a1ea42ecc75c4f18999d14fc42d1d255f84662a45003a52bb5840e977eb2ffd + languageName: node + linkType: hard + "csstype@npm:^3.0.7, csstype@npm:^3.1.2": version: 3.1.3 resolution: "csstype@npm:3.1.3" @@ -10508,13 +10121,6 @@ __metadata: languageName: node linkType: hard -"dayjs@npm:1.11.5": - version: 1.11.5 - resolution: "dayjs@npm:1.11.5" - checksum: e3bbaa7b4883b31be4bf75a181f1447fbb19800c29b332852125aab96baeff3ac232dcba8b88c4ea17d3b636c99dac5fb9d1af4bb6ae26615698bbc4a852dffb - languageName: node - linkType: hard - "dayjs@npm:^1.11.10": version: 1.11.13 resolution: "dayjs@npm:1.11.13" @@ -10759,13 +10365,6 @@ __metadata: languageName: node linkType: hard -"delayed-stream@npm:~1.0.0": - version: 1.0.0 - resolution: "delayed-stream@npm:1.0.0" - checksum: 46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 - languageName: node - linkType: hard - "delegates@npm:^1.0.0": version: 1.0.0 resolution: "delegates@npm:1.0.0" @@ -11060,7 +10659,7 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:16.3.1, dotenv@npm:^16.0.0": +"dotenv@npm:^16.0.0": version: 16.3.1 resolution: "dotenv@npm:16.3.1" checksum: 15d75e7279018f4bafd0ee9706593dd14455ddb71b3bcba9c52574460b7ccaf67d5cf8b2c08a5af1a9da6db36c956a04a1192b101ee102a3e0cf8817bbcf3dfd @@ -11772,86 +11371,6 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:~0.19.10": - version: 0.19.12 - resolution: "esbuild@npm:0.19.12" - dependencies: - "@esbuild/aix-ppc64": 0.19.12 - "@esbuild/android-arm": 0.19.12 - "@esbuild/android-arm64": 0.19.12 - "@esbuild/android-x64": 0.19.12 - "@esbuild/darwin-arm64": 0.19.12 - "@esbuild/darwin-x64": 0.19.12 - "@esbuild/freebsd-arm64": 0.19.12 - "@esbuild/freebsd-x64": 0.19.12 - "@esbuild/linux-arm": 0.19.12 - "@esbuild/linux-arm64": 0.19.12 - "@esbuild/linux-ia32": 0.19.12 - "@esbuild/linux-loong64": 0.19.12 - "@esbuild/linux-mips64el": 0.19.12 - "@esbuild/linux-ppc64": 0.19.12 - "@esbuild/linux-riscv64": 0.19.12 - "@esbuild/linux-s390x": 0.19.12 - "@esbuild/linux-x64": 0.19.12 - "@esbuild/netbsd-x64": 0.19.12 - "@esbuild/openbsd-x64": 0.19.12 - "@esbuild/sunos-x64": 0.19.12 - "@esbuild/win32-arm64": 0.19.12 - "@esbuild/win32-ia32": 0.19.12 - "@esbuild/win32-x64": 0.19.12 - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 2936e29107b43e65a775b78b7bc66ddd7d76febd73840ac7e825fb22b65029422ff51038a08d19b05154f543584bd3afe7d1ef1c63900429475b17fbe61cb61f - languageName: node - linkType: hard - "escalade@npm:^3.1.1": version: 3.1.1 resolution: "escalade@npm:3.1.1" @@ -12748,6 +12267,13 @@ __metadata: languageName: node linkType: hard +"eventsource-parser@npm:3.0.0": + version: 3.0.0 + resolution: "eventsource-parser@npm:3.0.0" + checksum: af7df874537a65e996568e5fed12db6eb27b4e041a70f5cc3a12b8b5b6f2ce229ba260d76b01f70f45ae0bf263e644d8f3768d24242f9ad86a8305991f61c7c0 + languageName: node + linkType: hard + "execa@npm:8.0.1, execa@npm:^8.0.1": version: 8.0.1 resolution: "execa@npm:8.0.1" @@ -12812,56 +12338,6 @@ __metadata: languageName: node linkType: hard -"express-ws@npm:5.0.2": - version: 5.0.2 - resolution: "express-ws@npm:5.0.2" - dependencies: - ws: ^7.4.6 - peerDependencies: - express: ^4.0.0 || ^5.0.0-alpha.1 - checksum: a7134c51b6a630a369bbc7e06b6fad9ec174d535dd76c990ea6285e6cb08abad408ddb1162ba347ec5725fc483ae9f035f2eecb22ea91f3ecebff05772f62f0b - languageName: node - linkType: hard - -"express@npm:4.19.2": - version: 4.19.2 - resolution: "express@npm:4.19.2" - dependencies: - accepts: ~1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.2 - content-disposition: 0.5.4 - content-type: ~1.0.4 - cookie: 0.6.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: ~1.0.2 - escape-html: ~1.0.3 - etag: ~1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: ~1.1.2 - on-finished: 2.4.1 - parseurl: ~1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: ~2.0.7 - qs: 6.11.0 - range-parser: ~1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: ~1.6.18 - utils-merge: 1.0.1 - vary: ~1.1.2 - checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 - languageName: node - linkType: hard - "express@npm:^4.17.3": version: 4.18.3 resolution: "express@npm:4.18.3" @@ -13192,16 +12668,6 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.15.6": - version: 1.15.6 - resolution: "follow-redirects@npm:1.15.6" - peerDependenciesMeta: - debug: - optional: true - checksum: a62c378dfc8c00f60b9c80cab158ba54e99ba0239a5dd7c81245e5a5b39d10f0c35e249c3379eae719ff0285fff88c365dd446fab19dee771f1d76252df1bbf5 - languageName: node - linkType: hard - "for-each@npm:^0.3.3": version: 0.3.3 resolution: "for-each@npm:0.3.3" @@ -13221,17 +12687,6 @@ __metadata: languageName: node linkType: hard -"form-data@npm:^4.0.0": - version: 4.0.0 - resolution: "form-data@npm:4.0.0" - dependencies: - asynckit: ^0.4.0 - combined-stream: ^1.0.8 - mime-types: ^2.1.12 - checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c - languageName: node - linkType: hard - "format@npm:^0.2.0": version: 0.2.2 resolution: "format@npm:0.2.2" @@ -13541,7 +12996,7 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.5.0, get-tsconfig@npm:^4.7.2": +"get-tsconfig@npm:^4.5.0": version: 4.7.3 resolution: "get-tsconfig@npm:4.7.3" dependencies: @@ -14153,17 +13608,6 @@ __metadata: languageName: node linkType: hard -"hast-util-sanitize@npm:^5.0.0": - version: 5.0.1 - resolution: "hast-util-sanitize@npm:5.0.1" - dependencies: - "@types/hast": ^3.0.0 - "@ungap/structured-clone": ^1.2.0 - unist-util-position: ^5.0.0 - checksum: cf7f3d1bb615f228fb90313adfd22ab4f7b2f34982d8d5aa86e3a5008964c0767de874b43530f2daae05823d16432783461c5dc4f45639018a3139d5363571de - languageName: node - linkType: hard - "hast-util-to-estree@npm:^3.0.0, hast-util-to-estree@npm:^3.1.0": version: 3.1.0 resolution: "hast-util-to-estree@npm:3.1.0" @@ -14327,13 +13771,6 @@ __metadata: languageName: node linkType: hard -"html-entities@npm:^2.4.0": - version: 2.5.2 - resolution: "html-entities@npm:2.5.2" - checksum: b23f4a07d33d49ade1994069af4e13d31650e3fb62621e92ae10ecdf01d1a98065c78fd20fdc92b4c7881612210b37c275f2c9fba9777650ab0d6f2ceb3b99b6 - languageName: node - linkType: hard - "html-escaper@npm:^2.0.0": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" @@ -14379,13 +13816,6 @@ __metadata: languageName: node linkType: hard -"htmlencode@npm:^0.0.4": - version: 0.0.4 - resolution: "htmlencode@npm:0.0.4" - checksum: b5c5a280213569f59807d22ae2d68c77360f6337b6936cdfa4e2aeaa12e3a69bb36b426ad18ed9333a7fb3f7d55c14ea3b46040d3271af7a586f262aaf4092ad - languageName: node - linkType: hard - "htmlparser2@npm:^7.1.2": version: 7.2.0 resolution: "htmlparser2@npm:7.2.0" @@ -14655,17 +14085,6 @@ __metadata: languageName: node linkType: hard -"intercom-client@npm:5.0.0": - version: 5.0.0 - resolution: "intercom-client@npm:5.0.0" - dependencies: - axios: ^1.6.0 - htmlencode: ^0.0.4 - lodash: ^4.17.21 - checksum: d60e8108e881712b07cd1c2e702c012c2581313f8a856f04f08ce35d904c29818db7f143c36bdf52606aaf4220bcb3959f9ad232b502ac40a05ea3bb3fcd7edd - languageName: node - linkType: hard - "internal-slot@npm:^1.0.3": version: 1.0.3 resolution: "internal-slot@npm:1.0.3" @@ -17347,7 +16766,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -17694,6 +17113,13 @@ __metadata: languageName: node linkType: hard +"nanoevents@npm:9.1.0": + version: 9.1.0 + resolution: "nanoevents@npm:9.1.0" + checksum: 77abbc15c4efc15518a0075b604e5db045e5d6184f4d08892c771928a84f53b1dd46138902213f66e8a9989e6c930168ca6441b80ff9098aec83c01a782bd42b + languageName: node + linkType: hard + "nanoid@npm:^3.3.6, nanoid@npm:^3.3.7": version: 3.3.7 resolution: "nanoid@npm:3.3.7" @@ -18103,7 +17529,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4, object-assign@npm:^4.1.1": +"object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f @@ -19233,13 +18659,6 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:^1.1.0": - version: 1.1.0 - resolution: "proxy-from-env@npm:1.1.0" - checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 - languageName: node - linkType: hard - "pseudomap@npm:^1.0.2": version: 1.0.2 resolution: "pseudomap@npm:1.0.2" @@ -19322,45 +18741,6 @@ __metadata: languageName: node linkType: hard -"ranges-apply@npm:^7.0.11": - version: 7.0.16 - resolution: "ranges-apply@npm:7.0.16" - dependencies: - ranges-merge: ^9.0.15 - tiny-invariant: ^1.3.3 - checksum: a6e90f67d62e6b3e47c23281ae4d087b5fae227071d43433cfabfbc17e76940c8bd40cdf5c76fc121494d5e3b8db747c90a2ff16b4d404cf767f35b4ef97e2e9 - languageName: node - linkType: hard - -"ranges-merge@npm:^9.0.15": - version: 9.0.15 - resolution: "ranges-merge@npm:9.0.15" - dependencies: - ranges-push: ^7.0.15 - ranges-sort: ^6.0.11 - checksum: c405307432e1ef395c7d573af5c7e37b15ddfddfaa063a3f13559733f254de1e1e77f98e23e100242e720f66dc19af5116eddfe9452ff134a15b30f97343957f - languageName: node - linkType: hard - -"ranges-push@npm:^7.0.11, ranges-push@npm:^7.0.15": - version: 7.0.15 - resolution: "ranges-push@npm:7.0.15" - dependencies: - codsen-utils: ^1.6.4 - ranges-sort: ^6.0.11 - string-collapse-leading-whitespace: ^7.0.7 - string-trim-spaces-only: ^5.0.10 - checksum: b7b22fd912998573f699900445ce62afda756c893c77511c32c43dd3bb1a65c1cf762818ec99aefba849540a55db862b84513725e8ec8ba650f2f30140c50928 - languageName: node - linkType: hard - -"ranges-sort@npm:^6.0.11": - version: 6.0.11 - resolution: "ranges-sort@npm:6.0.11" - checksum: 245f6f460f2d5696753702510a7ae5359794ba538898849fabc10c37d59b283f765151d0f146048ef6540c9b2a2fe677f25fe846d89cdf43333aefae5fe79c1a - languageName: node - linkType: hard - "raw-body@npm:2.5.2": version: 2.5.2 resolution: "raw-body@npm:2.5.2" @@ -19929,7 +19309,7 @@ __metadata: languageName: node linkType: hard -"rehype-raw@npm:7.0.0, rehype-raw@npm:^7.0.0": +"rehype-raw@npm:^7.0.0": version: 7.0.0 resolution: "rehype-raw@npm:7.0.0" dependencies: @@ -19940,16 +19320,6 @@ __metadata: languageName: node linkType: hard -"rehype-sanitize@npm:6.0.0": - version: 6.0.0 - resolution: "rehype-sanitize@npm:6.0.0" - dependencies: - "@types/hast": ^3.0.0 - hast-util-sanitize: ^5.0.0 - checksum: 8f1b44323a6012fbfa83ee6bc48163b846398952c60e5ddbd3d2275cb46cec4fb8d98a919ffce1b3322af469c6dcef9a0127bcf0a1d96203a5c193d07cd26742 - languageName: node - linkType: hard - "rehype-slug@npm:^6.0.0": version: 6.0.0 resolution: "rehype-slug@npm:6.0.0" @@ -20614,13 +19984,6 @@ __metadata: languageName: node linkType: hard -"rfdc@npm:^1.3.1": - version: 1.3.1 - resolution: "rfdc@npm:1.3.1" - checksum: d5d1e930aeac7e0e0a485f97db1356e388bdbeff34906d206fe524dd5ada76e95f186944d2e68307183fdc39a54928d4426bbb6734851692cfe9195efba58b79 - languageName: node - linkType: hard - "rimraf@npm:5.0.5": version: 5.0.5 resolution: "rimraf@npm:5.0.5" @@ -21605,45 +20968,6 @@ __metadata: languageName: node linkType: hard -"string-collapse-leading-whitespace@npm:^7.0.7": - version: 7.0.7 - resolution: "string-collapse-leading-whitespace@npm:7.0.7" - checksum: 76d82e928d67f1c356ca17c7889b3859625fd45447a5877e9637785e3518fbbfbdb7608d465aedb2ca06dc24b302ee4d46bb3d2bd73bd0ef908c14003c516d20 - languageName: node - linkType: hard - -"string-left-right@npm:^6.0.14": - version: 6.0.17 - resolution: "string-left-right@npm:6.0.17" - dependencies: - codsen-utils: ^1.6.4 - rfdc: ^1.3.1 - checksum: 5853b20a1f9c27052e4b34793a9dab28a43c369136e6deb3da6e18e5f4de00eb2d53b8a089c22738f252d84b6a309c93d88751257507d0becad75eee46e52e9d - languageName: node - linkType: hard - -"string-strip-html@npm:13.4.2": - version: 13.4.2 - resolution: "string-strip-html@npm:13.4.2" - dependencies: - "@types/lodash-es": ^4.17.8 - codsen-utils: ^1.6.1 - html-entities: ^2.4.0 - lodash-es: ^4.17.21 - ranges-apply: ^7.0.11 - ranges-push: ^7.0.11 - string-left-right: ^6.0.14 - checksum: d9c8a92e5abe180c2a3cfd5d2b9ce32dcb6019166a1993756babbb1b41de04cddec497a3fbac619bbd7857ca198a0d3961244a578f3e9a29617939ba7689fb34 - languageName: node - linkType: hard - -"string-trim-spaces-only@npm:^5.0.10": - version: 5.0.10 - resolution: "string-trim-spaces-only@npm:5.0.10" - checksum: e0e417c8bc5800bf018d7aec9d68312b019f7e2e961609be8de3dead28b3060fe5beb9cf4baeb54be9aaa9d47b8e91f5cde32b84f5c0e47b0dd67055b01e5d7e - languageName: node - linkType: hard - "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -22520,22 +21844,6 @@ __metadata: languageName: node linkType: hard -"tsx@npm:4.7.2": - version: 4.7.2 - resolution: "tsx@npm:4.7.2" - dependencies: - esbuild: ~0.19.10 - fsevents: ~2.3.3 - get-tsconfig: ^4.7.2 - dependenciesMeta: - fsevents: - optional: true - bin: - tsx: dist/cli.mjs - checksum: 34c4fbbfb96848e05e39d5c55da51815f0856386428ad781a6df79e88ad62d83e9a071a3997a230ea7b45654cb215262267ac1202c31b67056359d386f6a9f65 - languageName: node - linkType: hard - "turbo-darwin-64@npm:1.13.2": version: 1.13.2 resolution: "turbo-darwin-64@npm:1.13.2" @@ -23511,7 +22819,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:~1.1.2": +"vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: ae0123222c6df65b437669d63dfa8c36cee20a504101b2fcd97b8bf76f91259c17f9f2b4d70a1e3c6bbcee7f51b28392833adb6b2770b23b01abec84e369660b @@ -23693,17 +23001,6 @@ __metadata: languageName: node linkType: hard -"vite-plugin-fonts@npm:0.7.0": - version: 0.7.0 - resolution: "vite-plugin-fonts@npm:0.7.0" - dependencies: - fast-glob: ^3.2.11 - peerDependencies: - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 - checksum: 2e4cc4dd32f7dfee0bd8be8abc56051e70c5c9083edccac4166964da40304f5341c50bf4ff7e1e4c9bcd16955e52491a2d56ab07264b19442397cd4d9e4c312a - languageName: node - linkType: hard - "vite-plugin-html@npm:3.2.2": version: 3.2.2 resolution: "vite-plugin-html@npm:3.2.2" @@ -24313,36 +23610,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.18.0": - version: 8.18.0 - resolution: "ws@npm:8.18.0" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 91d4d35bc99ff6df483bdf029b9ea4bfd7af1f16fc91231a96777a63d263e1eabf486e13a2353970efc534f9faa43bdbf9ee76525af22f4752cbc5ebda333975 - languageName: node - linkType: hard - -"ws@npm:^7.4.6": - version: 7.5.9 - resolution: "ws@npm:7.5.9" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 - languageName: node - linkType: hard - "ws@npm:^8.2.3": version: 8.16.0 resolution: "ws@npm:8.16.0" From ed79b46500f7548455716be39a75e727a244ef3d Mon Sep 17 00:00:00 2001 From: Ben Teichman Date: Thu, 2 Jan 2025 20:14:10 -0500 Subject: [PATCH 3/5] feat: working client and simple streaming --- packages/chat/package.json | 1 - .../src/components/AgentMessage/index.tsx | 89 ------------------- .../SystemResponse/SystemMessage.tsx | 10 --- .../components/SystemResponse/constants.ts | 1 - .../src/components/SystemResponse/index.tsx | 1 + .../src/components/SystemResponse/types.ts | 10 --- .../traces/StreamedMessage.trace.ts | 37 +------- .../src/v2/interact-trace.stream.ts | 3 - yarn.lock | 8 -- 9 files changed, 5 insertions(+), 155 deletions(-) diff --git a/packages/chat/package.json b/packages/chat/package.json index 00e1ac8f3c..bf9650f924 100644 --- a/packages/chat/package.json +++ b/packages/chat/package.json @@ -87,7 +87,6 @@ "chroma-js": "2.4.2", "clsx": "1.2.1", "cuid": "2.1.8", - "nanoevents": "9.1.0", "react": "18.2.0", "react-dom": "18.2.0", "react-markdown": "9.0.0", diff --git a/packages/chat/src/components/AgentMessage/index.tsx b/packages/chat/src/components/AgentMessage/index.tsx index 4aad3fa090..972cd4db9c 100644 --- a/packages/chat/src/components/AgentMessage/index.tsx +++ b/packages/chat/src/components/AgentMessage/index.tsx @@ -10,7 +10,6 @@ import remarkGfm from 'remark-gfm'; import { FeedbackButton } from '../FeedbackButton'; import { FeedbackButtonVariant, type IFeedbackButton } from '../FeedbackButton/FeedbackButton.interface'; import { Icon } from '../Icon'; -import type { StreamedMessageProps } from '../SystemResponse'; import { agentMessageContainer, aiIconModifier, @@ -127,91 +126,3 @@ export const AgentMessage: React.FC = ({
    ); }; - -export const AgentStreamMessage: React.FC & StreamedMessageProps> = ({ - useStream, - children, - ai, - disclaimerMessage = 'Generated by AI, double-check for accuracy.', - isLast, - feedback, - textContent, -}) => { - const text = useStream(); - const content = typeof text === 'string' ? text : serializeToMarkdown(text); - - const isCodeBlock = content?.startsWith('```javascript'); - - return ( -
    - - - - - ) : ( -
    - {children} -
    - ); - }, - li: ({ children, ...props }) => { - // NOTE: this accounts for when the last item in a response is a li and we remove the bottom margin from that. - const position = props.node?.position; - if (position && position.end.offset === text.length - 1) { - return ( -
  • - {children} -
  • - ); - } - return
  • {children}
  • ; - }, - p: ({ children, ...props }) => { - const position = props.node?.position; - const isFirst = position && position.start.offset === 0; - const isLast = position && position.end.offset === text.length - 1; - return ( -

    - {children} -

    - ); - }, - }} - /> - {children &&
    {children}
    } - {ai && ( -
    - - {disclaimerMessage} -
    - )} - {feedback && !isLast && ( -
    - -
    - )} -
    - ); -}; diff --git a/packages/chat/src/components/SystemResponse/SystemMessage.tsx b/packages/chat/src/components/SystemResponse/SystemMessage.tsx index 793424095b..5b3dd38ea1 100644 --- a/packages/chat/src/components/SystemResponse/SystemMessage.tsx +++ b/packages/chat/src/components/SystemResponse/SystemMessage.tsx @@ -100,16 +100,6 @@ export const SystemMessage: React.FC = ({ textContent={textContent} /> )) - .with({ type: MessageType.STREAM }, ({ text, ai }) => ( - - )) .with({ type: MessageType.IMAGE }, ({ url }) => ) .with({ type: MessageType.CARD }, (props) => ) .with({ type: MessageType.EXTENSION }, ({ payload }) => ( diff --git a/packages/chat/src/components/SystemResponse/constants.ts b/packages/chat/src/components/SystemResponse/constants.ts index 647ae57c04..35e496fd94 100644 --- a/packages/chat/src/components/SystemResponse/constants.ts +++ b/packages/chat/src/components/SystemResponse/constants.ts @@ -1,6 +1,5 @@ export enum MessageType { TEXT = 'text', - STREAM = 'stream', IMAGE = 'image', CARD = 'card', CAROUSEL = 'carousel', diff --git a/packages/chat/src/components/SystemResponse/index.tsx b/packages/chat/src/components/SystemResponse/index.tsx index fab456a121..e1d1a88dd4 100644 --- a/packages/chat/src/components/SystemResponse/index.tsx +++ b/packages/chat/src/components/SystemResponse/index.tsx @@ -93,6 +93,7 @@ export const SystemResponse: React.FC = ({ }) => { const runtime = useContext(RuntimeStateAPIContext); + // TODO: undo changes to this file // const { showIndicator, visibleMessages, complete } = useAnimatedMessages({ // messages, // isLast, diff --git a/packages/chat/src/components/SystemResponse/types.ts b/packages/chat/src/components/SystemResponse/types.ts index 0579ceb712..faad5a2ee8 100644 --- a/packages/chat/src/components/SystemResponse/types.ts +++ b/packages/chat/src/components/SystemResponse/types.ts @@ -17,15 +17,6 @@ export interface TextMessageProps extends BaseMessageProps { audio?: { src: string }; } -export interface StreamedMessageProps extends BaseMessageProps { - type: StringifiedEnum; - text: string | Text.SlateTextValue; - - // // a promise that resolves when the stream is finished - // finished: Promise; - useStream: () => string; -} - export interface ImageMessageProps extends BaseMessageProps { type: StringifiedEnum; url: string | null; @@ -59,7 +50,6 @@ export interface CustomMessage extends BaseMessageProps { export type MessageProps = | TextMessageProps - | StreamedMessageProps | ImageMessageProps | CardMessageProps | CarouselMessageProps diff --git a/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts b/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts index 5330e15d44..2f8bd15248 100644 --- a/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts +++ b/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts @@ -1,8 +1,8 @@ import type { TraceDeclaration } from '@voiceflow/sdk-runtime'; -import { useEffect, useState } from 'react'; import { match } from 'ts-pattern'; -import type { StreamedMessageProps } from '@/components/SystemResponse'; +import type { TextMessageProps } from '@/components/SystemResponse'; +import { MessageType } from '@/components/SystemResponse/constants'; import type { RuntimeMessage } from '../messages'; @@ -32,7 +32,7 @@ interface CompletionTrace { export const StreamedMessage = (): TraceDeclaration => { let message: - | (StreamedMessageProps & { + | (TextMessageProps & { stream: TransformStream; }) | null = null; @@ -45,38 +45,9 @@ export const StreamedMessage = (): TraceDeclaration => { const stream = new TransformStream(); message = { - type: 'stream', + type: MessageType.TEXT, text: '', stream, - useStream: () => { - const [state, setState] = useState(''); - - useEffect(() => { - try { - const reader = stream.readable.getReader(); - - const read = async () => { - const { done, value } = await reader.read(); - - if (done) return; - - setState((prev) => prev + value); - }; - - read(); - - return () => { - reader.cancel(); - }; - } catch (e) { - console.error('cannot read stream', e); - } - - return undefined; - }, []); - - return state; - }, }; context.messages.push(message); }) diff --git a/packages/sdk-runtime/src/v2/interact-trace.stream.ts b/packages/sdk-runtime/src/v2/interact-trace.stream.ts index 9f75322465..09e91379a9 100644 --- a/packages/sdk-runtime/src/v2/interact-trace.stream.ts +++ b/packages/sdk-runtime/src/v2/interact-trace.stream.ts @@ -8,9 +8,6 @@ export class InteractTraceStream extends TransformStream ) { super({ - // start: () => {}, - // flush: () => {}, - transform: async (chunk, controller) => { const data = JSON.parse(chunk.data); const trace = await this.trace.processTrace(this.createContext(), data); diff --git a/yarn.lock b/yarn.lock index fa8255fd95..7e05527f46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7346,7 +7346,6 @@ __metadata: eslint-plugin-storybook: 0.8.0 happy-dom: 14.7.1 http-server: 14.1.1 - nanoevents: 9.1.0 react: 18.2.0 react-dom: 18.2.0 react-markdown: 9.0.0 @@ -17113,13 +17112,6 @@ __metadata: languageName: node linkType: hard -"nanoevents@npm:9.1.0": - version: 9.1.0 - resolution: "nanoevents@npm:9.1.0" - checksum: 77abbc15c4efc15518a0075b604e5db045e5d6184f4d08892c771928a84f53b1dd46138902213f66e8a9989e6c930168ca6441b80ff9098aec83c01a782bd42b - languageName: node - linkType: hard - "nanoid@npm:^3.3.6, nanoid@npm:^3.3.7": version: 3.3.7 resolution: "nanoid@npm:3.3.7" From 5d0637d65fd91cf62cb46a8bc4fa6a51a82d5a01 Mon Sep 17 00:00:00 2001 From: Ben Teichman Date: Thu, 2 Jan 2025 20:21:43 -0500 Subject: [PATCH 4/5] refactor: remove noise --- packages/sdk-runtime/src/sdk/sdk.service.ts | 2 +- packages/sdk-runtime/src/trace/trace.service.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/sdk-runtime/src/sdk/sdk.service.ts b/packages/sdk-runtime/src/sdk/sdk.service.ts index 89e6d6f3e6..9a039b3a4f 100644 --- a/packages/sdk-runtime/src/sdk/sdk.service.ts +++ b/packages/sdk-runtime/src/sdk/sdk.service.ts @@ -38,7 +38,7 @@ export class VoiceflowRuntime { public async interact(context: T, request: RuntimeInteractRequest): Promise { const response = await this.runtime.interact(request); - return this.trace.processResponse(context, response); + return this.trace.processTrace(context, response); } public async feedback(request: RuntimeFeedbackRequest) { diff --git a/packages/sdk-runtime/src/trace/trace.service.ts b/packages/sdk-runtime/src/trace/trace.service.ts index 5fa9276581..1eb510f863 100644 --- a/packages/sdk-runtime/src/trace/trace.service.ts +++ b/packages/sdk-runtime/src/trace/trace.service.ts @@ -6,7 +6,7 @@ export class TraceService { private readonly traces: TraceDeclaration[] = []; public constructor(options: TraceOptions = {}) { - this.traces = options.traces ?? []; + this.registerTraces(options.traces ?? []); } public registerTrace(step: TraceDeclaration): this { @@ -14,7 +14,12 @@ export class TraceService { return this; } - public async processResponse(context: T, response: Pick): Promise { + public registerTraces(steps: TraceDeclaration[]): this { + steps.forEach((step) => this.registerTrace(step)); + return this; + } + + public async processTrace(context: T, response: Pick): Promise { const meta: TraceHandlerMeta = { context }; for (const trace of response.trace) { From 89312f5d2afdaf8f3a59186a3d9f7a6cf90ee1d9 Mon Sep 17 00:00:00 2001 From: Mikaal Naik Date: Fri, 10 Jan 2025 08:56:10 -0500 Subject: [PATCH 5/5] fix: Streamed messages with animation and avatar (DSN-2653) (#505) --- .../AgentMessage/AgentMessage.css.ts | 1 + .../AgentMessage/AgentMessage.story.tsx | 6 +++ .../FeedbackButton.interface.ts | 2 +- .../src/components/FeedbackButton/index.tsx | 2 +- .../src/components/SystemResponse/index.tsx | 39 ++++++++----------- .../components/SystemResponse/styles.css.ts | 14 +------ .../src/components/SystemResponse/types.ts | 1 + .../traces/StreamedMessage.trace.ts | 2 - .../RuntimeContext/useRuntimeState.ts | 3 -- 9 files changed, 29 insertions(+), 41 deletions(-) diff --git a/packages/chat/src/components/AgentMessage/AgentMessage.css.ts b/packages/chat/src/components/AgentMessage/AgentMessage.css.ts index 0ab5a1dcbf..2ebcbfd48f 100644 --- a/packages/chat/src/components/AgentMessage/AgentMessage.css.ts +++ b/packages/chat/src/components/AgentMessage/AgentMessage.css.ts @@ -14,6 +14,7 @@ export const agentMessageContainer = style({ color: COLORS.NEUTRAL_DARK[900], fontFamily: THEME.fontFamily, position: 'relative', + minHeight: '41px', fontSize: '14px', lineHeight: '20px', borderRadius: SIZES.radius.sm, diff --git a/packages/chat/src/components/AgentMessage/AgentMessage.story.tsx b/packages/chat/src/components/AgentMessage/AgentMessage.story.tsx index 1fa1b3b0b3..da35cd7c02 100644 --- a/packages/chat/src/components/AgentMessage/AgentMessage.story.tsx +++ b/packages/chat/src/components/AgentMessage/AgentMessage.story.tsx @@ -28,6 +28,12 @@ export const Small: Story = { }, }; +export const Empty: Story = { + args: { + text: '', + }, +}; + export const AIGenerated: Story = { args: { text: SAMPLE_SLATE_TEXT as unknown as string, diff --git a/packages/chat/src/components/FeedbackButton/FeedbackButton.interface.ts b/packages/chat/src/components/FeedbackButton/FeedbackButton.interface.ts index 582a9d77a1..f2717fce93 100644 --- a/packages/chat/src/components/FeedbackButton/FeedbackButton.interface.ts +++ b/packages/chat/src/components/FeedbackButton/FeedbackButton.interface.ts @@ -11,7 +11,7 @@ export enum FeedbackButtonVariant { } export interface IFeedbackButton { - onClick: (feedback: FeedbackName) => void; + onClick?: (feedback: FeedbackName) => void; variant?: FeedbackButtonVariant; active?: boolean; textContent?: string; diff --git a/packages/chat/src/components/FeedbackButton/index.tsx b/packages/chat/src/components/FeedbackButton/index.tsx index d34d7fc58b..0e97ef0bee 100644 --- a/packages/chat/src/components/FeedbackButton/index.tsx +++ b/packages/chat/src/components/FeedbackButton/index.tsx @@ -34,7 +34,7 @@ export const FeedbackButton: React.FC = ({ variant, onClick, te }; const handleOnClick = (type: FeedbackName) => { - onClick(type); + onClick?.(type); setIsPositiveOrNegativeSelected(type); }; diff --git a/packages/chat/src/components/SystemResponse/index.tsx b/packages/chat/src/components/SystemResponse/index.tsx index e1d1a88dd4..537ba01fcb 100644 --- a/packages/chat/src/components/SystemResponse/index.tsx +++ b/packages/chat/src/components/SystemResponse/index.tsx @@ -91,15 +91,14 @@ export const SystemResponse: React.FC = ({ aiDisclaimer, Message = SystemMessage, }) => { - const runtime = useContext(RuntimeStateAPIContext); - // TODO: undo changes to this file - // const { showIndicator, visibleMessages, complete } = useAnimatedMessages({ - // messages, - // isLast, - // }); + const { showIndicator, complete } = useAnimatedMessages({ + messages, + isLast, + }); - // useAutoScroll([showIndicator, complete, messages.length]); + const runtime = useContext(RuntimeStateAPIContext); + useAutoScroll([showIndicator, complete, messages.length]); if (!messages.length && !actions.length) return null; @@ -120,6 +119,8 @@ export const SystemResponse: React.FC = ({ return acc; }, ''); + const messagesDisplayedToUser = messages.filter((message) => message.type !== MessageType.END); + return ( {messages.map((message, index) => { @@ -128,29 +129,23 @@ export const SystemResponse: React.FC = ({ return ; } - // const lastMessageInGroup = index === messages.length - 1; - - // Showing feedback on previous messages that were in the chat - const showFeedback = index === lastTextMessageIndex; // lastMessageInGroup && message.type === MessageType.TEXT; - - // // Showing feedback on the most recent system message of the chat - // const addFeedback = feedback && isLast && complete && lastMessageInGroup; - + const lastMessageInGroup = index === messagesDisplayedToUser.length - 1; + const showFeedback = index === lastTextMessageIndex; + const addFeedback = feedback && isLast && complete && showFeedback; return ( <> - {/* {addFeedback && message.type !== MessageType.CAROUSEL && ( + {showFeedback && message.type !== MessageType.CAROUSEL && (
    = ({ variant={FeedbackButtonVariant.LAST_RESPONSE} />
    - )} */} + )} ); })} - {/* {isLast && complete && !!actions.length && ( + {isLast && complete && !!actions.length && (
    {actions.map(({ request, name }, index) => (
    = ({ ))}
    )} - {showIndicator && } */} + {showIndicator && } ); }; diff --git a/packages/chat/src/components/SystemResponse/styles.css.ts b/packages/chat/src/components/SystemResponse/styles.css.ts index 7910877e2f..161034cbeb 100644 --- a/packages/chat/src/components/SystemResponse/styles.css.ts +++ b/packages/chat/src/components/SystemResponse/styles.css.ts @@ -1,10 +1,11 @@ -import { keyframes, style } from '@vanilla-extract/css'; +import { style } from '@vanilla-extract/css'; import { recipe } from '@vanilla-extract/recipes'; import { duration } from '@/styles/animations'; import { SIZES } from '@/styles/sizes'; import { SMALL_AVATAR_SIZE } from '../Avatar/styles.css'; +import { fadeInSlideUp } from '../UserResponse/styles.css'; export const MESSAGE_PADDING = 12; @@ -12,17 +13,6 @@ export const hide = style({ visibility: 'hidden', }); -const fadeInSlideUp = keyframes({ - from: { - opacity: 0, - transform: 'translateY(5px)', - }, - to: { - opacity: 1, - transform: 'translateY(0)', - }, -}); - export const systemMessageContainer = style({ display: 'flex', alignItems: 'flex-end', diff --git a/packages/chat/src/components/SystemResponse/types.ts b/packages/chat/src/components/SystemResponse/types.ts index faad5a2ee8..d5d7e3d02b 100644 --- a/packages/chat/src/components/SystemResponse/types.ts +++ b/packages/chat/src/components/SystemResponse/types.ts @@ -14,6 +14,7 @@ export interface BaseMessageProps { export interface TextMessageProps extends BaseMessageProps { type: StringifiedEnum; text: string | Text.SlateTextValue; + stream?: TransformStream | null; audio?: { src: string }; } diff --git a/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts b/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts index 2f8bd15248..5a7c178585 100644 --- a/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts +++ b/packages/chat/src/contexts/RuntimeContext/traces/StreamedMessage.trace.ts @@ -65,8 +65,6 @@ export const StreamedMessage = (): TraceDeclaration => { writer.releaseLock(); message.text += content; - - console.log('message', message.text); }) .exhaustive(); diff --git a/packages/chat/src/contexts/RuntimeContext/useRuntimeState.ts b/packages/chat/src/contexts/RuntimeContext/useRuntimeState.ts index 126ca3a299..a489276dd9 100644 --- a/packages/chat/src/contexts/RuntimeContext/useRuntimeState.ts +++ b/packages/chat/src/contexts/RuntimeContext/useRuntimeState.ts @@ -110,9 +110,6 @@ export const useRuntimeState = ({ assistant, config, traceHandlers }: Settings) actions: data.actions ?? turn.actions, }); - console.log('updated', cloned); - console.log('data', data); - return cloned; });