@pipecat-ai/client-react 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"mappings":"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","sources":["client-react/src/index.ts","client-react/src/PipecatClientAudio.tsx","client-react/src/usePipecatClientMediaTrack.ts","client-react/src/usePipecatClient.ts","client-react/src/PipecatClientProvider.tsx","client-react/package.json","client-react/src/conversation/PipecatConversationProvider.tsx","client-react/src/conversation/conversationActions.ts","client-react/src/conversation/botOutput.ts","client-react/src/conversation/conversationAtoms.ts","client-react/src/conversation/utils.ts","client-react/src/conversation/useConversationEventWiring.ts","client-react/src/useRTVIClientEvent.ts","client-react/src/RTVIEventContext.ts","client-react/src/PipecatClientState.tsx","client-react/src/PipecatClientCamToggle.tsx","client-react/src/usePipecatClientCamControl.ts","client-react/src/PipecatClientMicToggle.tsx","client-react/src/usePipecatClientMicControl.ts","client-react/src/PipecatClientScreenShareToggle.tsx","client-react/src/usePipecatClientScreenShareControl.ts","client-react/src/PipecatClientVideo.tsx","client-react/src/useMergedRef.ts","client-react/src/usePipecatClientMediaDevices.ts","client-react/src/usePipecatClientTransportState.ts","client-react/src/VoiceVisualizer.tsx","client-react/src/usePipecatConversation.ts"],"sourcesContent":["/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { PipecatClientAudio } from \"./PipecatClientAudio\";\nimport { PipecatClientCamToggle } from \"./PipecatClientCamToggle\";\nimport { PipecatClientMicToggle } from \"./PipecatClientMicToggle\";\nimport { PipecatClientProvider } from \"./PipecatClientProvider\";\nimport { PipecatClientScreenShareToggle } from \"./PipecatClientScreenShareToggle\";\nimport { PipecatClientVideo } from \"./PipecatClientVideo\";\nimport { usePipecatClient } from \"./usePipecatClient\";\nimport { usePipecatClientCamControl } from \"./usePipecatClientCamControl\";\nimport { usePipecatClientMediaDevices } from \"./usePipecatClientMediaDevices\";\nimport { usePipecatClientMediaTrack } from \"./usePipecatClientMediaTrack\";\nimport { usePipecatClientMicControl } from \"./usePipecatClientMicControl\";\nimport { usePipecatClientScreenShareControl } from \"./usePipecatClientScreenShareControl\";\nimport { usePipecatClientTransportState } from \"./usePipecatClientTransportState\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\nimport {\n deduplicateFunctionCalls,\n filterEmptyMessages,\n isMessageEmpty,\n mergeMessages,\n sortByCreatedAt,\n} from \"./conversation/conversationActions\";\nimport { useConversationContext } from \"./conversation/PipecatConversationProvider\";\nimport { usePipecatConversation } from \"./usePipecatConversation\";\n\nexport {\n PipecatClientAudio,\n PipecatClientCamToggle,\n PipecatClientMicToggle,\n PipecatClientProvider,\n PipecatClientScreenShareToggle,\n PipecatClientVideo,\n usePipecatClient,\n usePipecatClientCamControl,\n usePipecatClientMediaDevices,\n usePipecatClientMediaTrack,\n usePipecatClientMicControl,\n usePipecatClientScreenShareControl,\n usePipecatClientTransportState,\n useRTVIClientEvent,\n VoiceVisualizer,\n // Conversation\n useConversationContext,\n usePipecatConversation,\n deduplicateFunctionCalls,\n filterEmptyMessages,\n isMessageEmpty,\n mergeMessages,\n sortByCreatedAt,\n};\n\n// Conversation types\nexport type {\n AggregationMetadata,\n BotOutputText,\n ConversationMessage,\n ConversationMessagePart,\n FunctionCallData,\n FunctionCallRenderer,\n} from \"./conversation/types\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport { usePipecatClientMediaTrack } from \"./usePipecatClientMediaTrack\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\nexport const PipecatClientAudio = () => {\n const botAudioRef = useRef<HTMLAudioElement>(null);\n const botAudioTrack = usePipecatClientMediaTrack(\"audio\", \"bot\");\n\n useEffect(() => {\n if (!botAudioRef.current || !botAudioTrack) return;\n if (botAudioRef.current.srcObject) {\n const oldTrack = (\n botAudioRef.current.srcObject as MediaStream\n ).getAudioTracks()[0];\n if (oldTrack.id === botAudioTrack.id) return;\n }\n botAudioRef.current.srcObject = new MediaStream([botAudioTrack]);\n }, [botAudioTrack]);\n\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useCallback((speaker: MediaDeviceInfo) => {\n if (!botAudioRef.current) return;\n if (typeof botAudioRef.current.setSinkId !== \"function\") return;\n botAudioRef.current.setSinkId(speaker.deviceId);\n }, [])\n );\n\n return (\n <>\n <audio ref={botAudioRef} autoPlay />\n </>\n );\n};\nPipecatClientAudio.displayName = \"PipecatClientAudio\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { Participant, RTVIEvent, Tracks } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { atomFamily, useAtomCallback } from \"jotai/utils\";\nimport { PrimitiveAtom } from \"jotai/vanilla\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { usePipecatClient } from \"./usePipecatClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype ParticipantType = keyof Tracks;\ntype TrackType = keyof Tracks[\"local\"];\n\nconst localAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botVideoTrackAtom = atom<MediaStreamTrack | null>(null);\n\nconst trackAtom = atomFamily<\n { local: boolean; trackType: TrackType },\n PrimitiveAtom<MediaStreamTrack | null>\n>(({ local, trackType }) => {\n if (local) {\n switch (trackType) {\n case \"audio\":\n return localAudioTrackAtom;\n case \"screenAudio\":\n return localScreenAudioTrackAtom;\n case \"screenVideo\":\n return localScreenVideoTrackAtom;\n case \"video\":\n return localVideoTrackAtom;\n }\n }\n return trackType === \"audio\" ? botAudioTrackAtom : botVideoTrackAtom;\n});\n\nexport const usePipecatClientMediaTrack = (\n trackType: TrackType,\n participantType: ParticipantType\n) => {\n const client = usePipecatClient();\n const track = useAtomValue(\n trackAtom({ local: participantType === \"local\", trackType })\n );\n\n const updateTrack = useAtomCallback(\n useCallback(\n (\n get,\n set,\n track: MediaStreamTrack,\n trackType: TrackType,\n local: boolean\n ) => {\n const atom = trackAtom({\n local,\n trackType,\n });\n const oldTrack = get(atom);\n if (oldTrack?.id === track.id) return;\n set(atom, track);\n },\n []\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.TrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n updateTrack(\n track,\n track.kind as TrackType,\n Boolean(participant?.local)\n );\n },\n [updateTrack]\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.ScreenTrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n const trackType =\n track.kind === \"audio\" ? \"screenAudio\" : \"screenVideo\";\n updateTrack(track, trackType, Boolean(participant?.local));\n },\n [updateTrack]\n )\n );\n\n useEffect(() => {\n if (!client) return;\n const tracks = client.tracks();\n const track = tracks?.[participantType]?.[trackType];\n if (!track) return;\n updateTrack(track, trackType, participantType === \"local\");\n }, [participantType, trackType, updateTrack, client]);\n\n return track;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { PipecatClientContext } from \"./PipecatClientProvider\";\n\nexport const usePipecatClient = () => {\n const { client } = useContext(PipecatClientContext);\n return client;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport {\n PipecatClient,\n RTVIEvent,\n RTVIEventHandler,\n setAboutClient,\n} from \"@pipecat-ai/client-js\";\nimport { createStore } from \"jotai\";\nimport { Provider as JotaiProvider } from \"jotai/react\";\nimport React, { createContext, useCallback, useEffect, useRef } from \"react\";\n\nimport {\n name as packageName,\n version as packageVersion,\n} from \"../package.json\";\nimport { PipecatConversationProvider } from \"./conversation/PipecatConversationProvider\";\nimport { PipecatClientStateProvider } from \"./PipecatClientState\";\nimport { RTVIEventContext } from \"./RTVIEventContext\";\n\nexport interface Props {\n client: PipecatClient;\n jotaiStore?: React.ComponentProps<typeof JotaiProvider>[\"store\"];\n}\n\nconst defaultStore = createStore();\n\nexport const PipecatClientContext = createContext<{ client?: PipecatClient }>(\n {}\n);\n\ntype EventHandlersMap = {\n [E in RTVIEvent]?: Set<RTVIEventHandler<E>>;\n};\n\nexport const PipecatClientProvider: React.FC<\n React.PropsWithChildren<Props>\n> = ({ children, client, jotaiStore = defaultStore }) => {\n useEffect(() => {\n setAboutClient({\n library: packageName,\n library_version: packageVersion,\n });\n }, []);\n\n const eventHandlersMap = useRef<EventHandlersMap>({});\n\n useEffect(() => {\n if (!client) return;\n\n const allEvents = Object.values(RTVIEvent).filter((value) =>\n isNaN(Number(value))\n ) as RTVIEvent[];\n\n const allHandlers: Partial<\n Record<\n RTVIEvent,\n (\n ...args: Parameters<Exclude<RTVIEventHandler<RTVIEvent>, undefined>>\n ) => void\n >\n > = {};\n\n allEvents.forEach((event) => {\n type E = typeof event;\n type Handler = Exclude<RTVIEventHandler<E>, undefined>; // Remove undefined\n type Payload = Parameters<Handler>; // Will always be a tuple\n\n const handler = (...payload: Payload) => {\n const handlers = eventHandlersMap.current[event] as\n | Set<Handler>\n | undefined;\n if (!handlers) return;\n handlers.forEach((h) => {\n (\n h as (\n ...args: Parameters<Exclude<RTVIEventHandler<E>, undefined>>\n ) => void\n )(...payload);\n });\n };\n\n allHandlers[event] = handler;\n\n client.on(event, handler);\n });\n\n return () => {\n allEvents.forEach((event) => {\n client.off(event, allHandlers[event]);\n });\n };\n }, [client]);\n\n const on = useCallback(\n <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => {\n if (!eventHandlersMap.current[event]) {\n eventHandlersMap.current[event] = new Set();\n }\n eventHandlersMap.current[event]!.add(handler);\n },\n []\n );\n\n const off = useCallback(\n <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => {\n eventHandlersMap.current[event]?.delete(handler);\n },\n []\n );\n\n return (\n <JotaiProvider store={jotaiStore}>\n <PipecatClientContext.Provider value={{ client }}>\n <RTVIEventContext.Provider value={{ on, off }}>\n <PipecatClientStateProvider>\n <PipecatConversationProvider>\n {children}\n </PipecatConversationProvider>\n </PipecatClientStateProvider>\n </RTVIEventContext.Provider>\n </PipecatClientContext.Provider>\n </JotaiProvider>\n );\n};\nPipecatClientProvider.displayName = \"PipecatClientProvider\";\n","{\n \"name\": \"@pipecat-ai/client-react\",\n \"version\": \"1.2.0\",\n \"license\": \"BSD-2-Clause\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.module.js\",\n \"types\": \"dist/index.d.ts\",\n \"source\": \"src/index.ts\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/pipecat-ai/pipecat-client-web.git\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.module.js\",\n \"require\": \"./dist/index.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"package.json\",\n \"README.md\"\n ],\n \"scripts\": {\n \"build\": \"parcel build --no-cache\",\n \"dev\": \"parcel watch\",\n \"lint\": \"eslint . --report-unused-disable-directives --max-warnings 0 --ignore-pattern 'dist/'\",\n \"test\": \"jest\"\n },\n \"jest\": {\n \"preset\": \"ts-jest\",\n \"testEnvironment\": \"jsdom\",\n \"moduleNameMapper\": {\n \"^@/(.*)$\": \"<rootDir>/src/$1\"\n },\n \"transform\": {\n \"^.+\\\\.tsx?$\": [\n \"ts-jest\",\n {\n \"tsconfig\": {\n \"jsx\": \"react-jsx\",\n \"module\": \"commonjs\",\n \"moduleResolution\": \"node\",\n \"esModuleInterop\": true,\n \"allowImportingTsExtensions\": false,\n \"noUnusedLocals\": false,\n \"noUnusedParameters\": false\n }\n }\n ]\n }\n },\n \"devDependencies\": {\n \"@jest/globals\": \"^30.2.0\",\n \"@pipecat-ai/client-js\": \"*\",\n \"@types/jest\": \"^30.0.0\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@typescript-eslint/eslint-plugin\": \"^8.32.0\",\n \"eslint\": \"^9.11.1\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"eslint-plugin-react-hooks\": \"^5.2.0\",\n \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n \"jest\": \"^30.2.0\",\n \"jest-environment-jsdom\": \"^30.2.0\",\n \"parcel\": \"^2.12.0\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"ts-jest\": \"^29.4.6\",\n \"typescript\": \"^5.2.2\"\n },\n \"peerDependencies\": {\n \"@pipecat-ai/client-js\": \"*\",\n \"react\": \">=18\",\n \"react-dom\": \">=18\"\n },\n \"dependencies\": {\n \"jotai\": \"^2.9.0\"\n }\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport React, { createContext, useCallback, useContext } from \"react\";\n\nimport { injectMessage as injectMessageAction } from \"./conversationActions\";\nimport { botOutputSupportedAtom } from \"./conversationAtoms\";\nimport type { ConversationMessagePart } from \"./types\";\nimport { useConversationEventWiring } from \"./useConversationEventWiring\";\n\ninterface ConversationContextValue {\n injectMessage: (message: {\n role: \"user\" | \"assistant\" | \"system\";\n parts: ConversationMessagePart[];\n }) => void;\n /**\n * Whether BotOutput events are supported (RTVI 1.1.0+)\n * null = unknown (before BotReady), true = supported, false = not supported\n */\n botOutputSupported: boolean | null;\n}\n\nexport const ConversationContext =\n createContext<ConversationContextValue | null>(null);\n\nexport const PipecatConversationProvider: React.FC<React.PropsWithChildren> = ({\n children,\n}) => {\n useConversationEventWiring();\n\n const injectMessage = useAtomCallback(\n useCallback((get, set, message: {\n role: \"user\" | \"assistant\" | \"system\";\n parts: ConversationMessagePart[];\n }) => {\n injectMessageAction(get, set, message);\n }, [])\n );\n\n const botOutputSupported = useAtomValue(botOutputSupportedAtom);\n\n return (\n <ConversationContext.Provider value={{ injectMessage, botOutputSupported }}>\n {children}\n </ConversationContext.Provider>\n );\n};\nPipecatConversationProvider.displayName = \"PipecatConversationProvider\";\n\nexport const useConversationContext = (): ConversationContextValue => {\n const context = useContext(ConversationContext);\n if (!context) {\n throw new Error(\n \"useConversationContext must be used within a PipecatClientProvider\"\n );\n }\n return context;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport type { Getter, Setter } from \"jotai\";\nimport type { ReactNode } from \"react\";\n\nimport { applySpokenBotOutputProgress } from \"./botOutput\";\nimport type { MessageCallbacks } from \"./conversationAtoms\";\nimport {\n botOutputMessageStateAtom,\n messageCallbacksAtom,\n messagesAtom,\n} from \"./conversationAtoms\";\nimport type {\n BotOutputText,\n ConversationMessage,\n ConversationMessagePart,\n FunctionCallData,\n} from \"./types\";\nimport { findLast, findLastIndex } from \"./utils\";\n\n/** Max time gap (ms) between consecutive same-role messages for merging. */\nconst MERGE_WINDOW_MS = 30_000;\n\n// ---------------------------------------------------------------------------\n// Public utility functions (exported for consumers)\n// ---------------------------------------------------------------------------\n\nexport const sortByCreatedAt = (\n a: ConversationMessage,\n b: ConversationMessage\n): number => {\n return a.createdAt < b.createdAt ? -1 : a.createdAt > b.createdAt ? 1 : 0;\n};\n\nexport const isMessageEmpty = (message: ConversationMessage): boolean => {\n if (message.role === \"function_call\") return false;\n const parts = message.parts || [];\n if (parts.length === 0) return true;\n return parts.every((p) => {\n if (typeof p.text === \"string\") {\n return p.text.trim().length === 0;\n }\n // Check BotOutputText objects\n if (\n typeof p.text === \"object\" &&\n p.text !== null &&\n \"spoken\" in p.text &&\n \"unspoken\" in p.text\n ) {\n const botText = p.text as BotOutputText;\n return (\n botText.spoken.trim().length === 0 &&\n botText.unspoken.trim().length === 0\n );\n }\n // For ReactNode, consider it non-empty\n return false;\n });\n};\n\nexport const filterEmptyMessages = (\n messages: ConversationMessage[]\n): ConversationMessage[] => {\n return messages.filter((message, index, array) => {\n if (!isMessageEmpty(message)) return true;\n\n // For empty messages, keep only if no following non-empty message with same role\n const nextMessageWithSameRole = array\n .slice(index + 1)\n .find((m) => m.role === message.role && !isMessageEmpty(m));\n\n return !nextMessageWithSameRole;\n });\n};\n\nexport const mergeMessages = (\n messages: ConversationMessage[]\n): ConversationMessage[] => {\n const mergedMessages: ConversationMessage[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const currentMessage = messages[i];\n const lastMerged = mergedMessages[mergedMessages.length - 1];\n\n const timeDiff = lastMerged\n ? Math.abs(\n new Date(currentMessage.createdAt).getTime() -\n new Date(lastMerged.createdAt).getTime()\n )\n : Infinity;\n\n const shouldMerge =\n lastMerged &&\n lastMerged.role === currentMessage.role &&\n currentMessage.role !== \"system\" &&\n currentMessage.role !== \"function_call\" &&\n timeDiff < MERGE_WINDOW_MS;\n\n if (shouldMerge) {\n mergedMessages[mergedMessages.length - 1] = {\n ...lastMerged,\n parts: [...(lastMerged.parts || []), ...(currentMessage.parts || [])],\n updatedAt: currentMessage.updatedAt || currentMessage.createdAt,\n final: currentMessage.final !== false,\n };\n } else {\n mergedMessages.push(currentMessage);\n }\n }\n\n return mergedMessages;\n};\n\nconst statusPriority: Record<string, number> = {\n started: 0,\n in_progress: 1,\n completed: 2,\n};\n\n/**\n * Deduplicate function call messages that share the same tool_call_id,\n * keeping the entry with the most advanced status.\n */\nexport const deduplicateFunctionCalls = (\n messages: ConversationMessage[]\n): ConversationMessage[] => {\n const bestByToolCallId = new Map<string, number>();\n const toRemove = new Set<number>();\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n const tcid = msg.functionCall?.tool_call_id;\n if (msg.role !== \"function_call\" || !tcid) continue;\n\n const existingIdx = bestByToolCallId.get(tcid);\n if (existingIdx !== undefined) {\n const existingPriority =\n statusPriority[messages[existingIdx].functionCall!.status] ?? 0;\n const currentPriority = statusPriority[msg.functionCall!.status] ?? 0;\n\n if (currentPriority >= existingPriority) {\n toRemove.add(existingIdx);\n bestByToolCallId.set(tcid, i);\n } else {\n toRemove.add(i);\n }\n } else {\n bestByToolCallId.set(tcid, i);\n }\n }\n\n if (toRemove.size === 0) return messages;\n return messages.filter((_, i) => !toRemove.has(i));\n};\n\nconst normalizeMessagesForUI = (\n messages: ConversationMessage[]\n): ConversationMessage[] => {\n return mergeMessages(\n deduplicateFunctionCalls(\n filterEmptyMessages([...messages].sort(sortByCreatedAt))\n )\n );\n};\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst callCallbacks = (\n callbacksMap: Map<string, MessageCallbacks>,\n type: keyof MessageCallbacks,\n message: ConversationMessage\n) => {\n callbacksMap.forEach((callbacks) => {\n try {\n callbacks[type]?.(message);\n } catch (error) {\n console.error(`Error in ${type} callback:`, error);\n }\n });\n};\n\n// ---------------------------------------------------------------------------\n// Action functions – (get, set, …params) => void\n// ---------------------------------------------------------------------------\n\nexport function registerMessageCallback(\n get: Getter,\n set: Setter,\n id: string,\n callbacks: MessageCallbacks\n) {\n const map = new Map(get(messageCallbacksAtom));\n map.set(id, callbacks);\n set(messageCallbacksAtom, map);\n}\n\nexport function unregisterMessageCallback(\n get: Getter,\n set: Setter,\n id: string\n) {\n const map = new Map(get(messageCallbacksAtom));\n map.delete(id);\n set(messageCallbacksAtom, map);\n}\n\nexport function clearMessages(_get: Getter, set: Setter) {\n set(messagesAtom, []);\n set(botOutputMessageStateAtom, new Map());\n}\n\nexport function addMessage(\n get: Getter,\n set: Setter,\n messageData: Omit<ConversationMessage, \"createdAt\" | \"updatedAt\">\n) {\n const now = new Date();\n const message: ConversationMessage = {\n ...messageData,\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n };\n\n const current = get(messagesAtom);\n const updatedMessages = [...current, message];\n const processedMessages = normalizeMessagesForUI(updatedMessages);\n\n callCallbacks(get(messageCallbacksAtom), \"onMessageCreated\", message);\n set(messagesAtom, processedMessages);\n}\n\nexport function updateLastMessage(\n get: Getter,\n set: Setter,\n role: \"user\" | \"assistant\",\n updates: Partial<ConversationMessage>\n) {\n const messages = [...get(messagesAtom)];\n const lastMessageIndex = findLastIndex(messages,(msg) => msg.role === role);\n\n if (lastMessageIndex === -1) return;\n\n const existing = messages[lastMessageIndex];\n const updatedMessage = {\n ...existing,\n ...updates,\n updatedAt: new Date().toISOString(),\n } as ConversationMessage;\n\n messages[lastMessageIndex] = updatedMessage;\n const processedMessages = normalizeMessagesForUI(messages);\n\n callCallbacks(get(messageCallbacksAtom), \"onMessageUpdated\", updatedMessage);\n set(messagesAtom, processedMessages);\n}\n\nexport function finalizeLastMessage(\n get: Getter,\n set: Setter,\n role: \"user\" | \"assistant\"\n) {\n const messages = [...get(messagesAtom)];\n const lastMessageIndex = findLastIndex(messages,(msg) => msg.role === role);\n\n if (lastMessageIndex === -1) return;\n\n const lastMessage = messages[lastMessageIndex];\n\n // Check if message is empty\n if (isMessageEmpty(lastMessage)) {\n // Remove empty message only if it has no text in streams either\n messages.splice(lastMessageIndex, 1);\n } else {\n // Finalize message and its last part\n const parts = [...(lastMessage.parts || [])];\n if (parts.length > 0) {\n parts[parts.length - 1] = {\n ...parts[parts.length - 1],\n final: true,\n };\n }\n messages[lastMessageIndex] = {\n ...lastMessage,\n parts,\n final: true,\n updatedAt: new Date().toISOString(),\n };\n callCallbacks(\n get(messageCallbacksAtom),\n \"onMessageUpdated\",\n messages[lastMessageIndex]\n );\n }\n\n const processedMessages = normalizeMessagesForUI(messages);\n set(messagesAtom, processedMessages);\n}\n\nexport function removeEmptyLastMessage(\n get: Getter,\n set: Setter,\n role: \"user\" | \"assistant\"\n) {\n const messages = [...get(messagesAtom)];\n const lastMessageIndex = findLastIndex(messages,(msg) => msg.role === role);\n\n if (lastMessageIndex === -1) return;\n\n const lastMessage = messages[lastMessageIndex];\n\n if (isMessageEmpty(lastMessage)) {\n messages.splice(lastMessageIndex, 1);\n const processedMessages = normalizeMessagesForUI(messages);\n set(messagesAtom, processedMessages);\n }\n}\n\nexport function injectMessage(\n get: Getter,\n set: Setter,\n messageData: {\n role: \"user\" | \"assistant\" | \"system\";\n parts: ConversationMessagePart[];\n }\n) {\n const now = new Date();\n const message: ConversationMessage = {\n role: messageData.role,\n final: true,\n parts: [...messageData.parts],\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n };\n\n const current = get(messagesAtom);\n const updatedMessages = [...current, message];\n const processedMessages = normalizeMessagesForUI(updatedMessages);\n\n callCallbacks(get(messageCallbacksAtom), \"onMessageCreated\", message);\n set(messagesAtom, processedMessages);\n}\n\nexport function upsertUserTranscript(\n get: Getter,\n set: Setter,\n text: string | ReactNode,\n final: boolean\n) {\n const now = new Date();\n const messages = [...get(messagesAtom)];\n\n // Find last user message\n const lastUserIndex = findLastIndex(messages,(m) => m.role === \"user\");\n\n if (lastUserIndex !== -1 && !messages[lastUserIndex].final) {\n // Update existing user message\n const target = { ...messages[lastUserIndex] };\n const parts: ConversationMessagePart[] = Array.isArray(target.parts)\n ? [...target.parts]\n : [];\n\n const lastPart = parts[parts.length - 1];\n if (!lastPart || lastPart.final) {\n // Start a new part\n parts.push({ text, final, createdAt: now.toISOString() });\n } else {\n // Update in-progress part\n parts[parts.length - 1] = {\n ...lastPart,\n text,\n final,\n };\n }\n\n const updatedMessage: ConversationMessage = {\n ...target,\n parts,\n updatedAt: now.toISOString(),\n };\n\n messages[lastUserIndex] = updatedMessage;\n\n const processedMessages = normalizeMessagesForUI(messages);\n\n callCallbacks(get(messageCallbacksAtom), \"onMessageUpdated\", updatedMessage);\n set(messagesAtom, processedMessages);\n return;\n }\n\n // Create a new user message initialized with this transcript\n const newMessage: ConversationMessage = {\n role: \"user\",\n final: false,\n parts: [\n {\n text,\n final,\n createdAt: now.toISOString(),\n },\n ],\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n };\n\n const updatedMessages = [...messages, newMessage];\n const processedMessages = normalizeMessagesForUI(updatedMessages);\n callCallbacks(get(messageCallbacksAtom), \"onMessageCreated\", newMessage);\n set(messagesAtom, processedMessages);\n}\n\nexport function updateAssistantBotOutput(\n get: Getter,\n set: Setter,\n text: string,\n final: boolean,\n spoken: boolean,\n aggregatedBy?: string\n) {\n const now = new Date();\n const messages = [...get(messagesAtom)];\n const botOutputMessageState = new Map(get(botOutputMessageStateAtom));\n\n const lastAssistantIndex = findLastIndex(messages,\n (msg) => msg.role === \"assistant\"\n );\n\n let messageId: string;\n let isNewMessage = false;\n\n if (lastAssistantIndex === -1) {\n // Create new assistant message\n isNewMessage = true;\n messageId = now.toISOString();\n const newMessage: ConversationMessage = {\n role: \"assistant\",\n final,\n parts: [],\n createdAt: messageId,\n updatedAt: messageId,\n };\n messages.push(newMessage);\n // Initialize message state\n botOutputMessageState.set(messageId, {\n currentPartIndex: 0,\n currentCharIndex: 0,\n partFinalFlags: [],\n });\n } else {\n // Update existing assistant message\n const lastMessage = messages[lastAssistantIndex];\n messageId = lastMessage.createdAt;\n\n messages[lastAssistantIndex] = {\n ...lastMessage,\n final: final ? true : lastMessage.final,\n updatedAt: now.toISOString(),\n };\n\n // Ensure message state exists\n if (!botOutputMessageState.has(messageId)) {\n botOutputMessageState.set(messageId, {\n currentPartIndex: 0,\n currentCharIndex: 0,\n partFinalFlags: [],\n });\n }\n }\n\n const messageState = botOutputMessageState.get(messageId)!;\n const message =\n messages[\n lastAssistantIndex === -1 ? messages.length - 1 : lastAssistantIndex\n ];\n const parts = [...(message.parts || [])];\n\n if (!spoken) {\n // UNSPOKEN EVENT: Create/update message parts immediately\n // Only append when both current and last part are word-level; sentence-level\n // and other types each get their own part so spoken events can match 1:1.\n const isDefaultType =\n aggregatedBy === \"sentence\" ||\n aggregatedBy === \"word\" ||\n !aggregatedBy;\n const lastPart = parts[parts.length - 1];\n const shouldAppend =\n lastPart &&\n aggregatedBy === \"word\" &&\n lastPart.aggregatedBy === \"word\" &&\n typeof lastPart.text === \"string\";\n\n if (shouldAppend) {\n // Append to last part (word-level only)\n const lastPartText = lastPart.text as string;\n const separator =\n lastPartText && !lastPartText.endsWith(\" \") && !text.startsWith(\" \")\n ? \" \"\n : \"\";\n parts[parts.length - 1] = {\n ...lastPart,\n text: lastPartText + separator + text,\n };\n } else {\n // Create new part (sentence-level, custom types, or first word chunk)\n // Default to inline; custom types get displayMode from metadata in the hook\n const defaultDisplayMode = isDefaultType ? \"inline\" : undefined;\n const newPart: ConversationMessagePart = {\n text: text, // Store full text as string\n final: false, // Will be evaluated in hook based on metadata\n createdAt: now.toISOString(),\n aggregatedBy,\n displayMode: defaultDisplayMode,\n };\n parts.push(newPart);\n // Extend partFinalFlags array\n messageState.partFinalFlags.push(false);\n }\n\n // Update message with new parts\n messages[\n lastAssistantIndex === -1 ? messages.length - 1 : lastAssistantIndex\n ] = {\n ...message,\n parts,\n };\n } else {\n // SPOKEN EVENT: advance cursor into existing text, or add as new part if\n // there is none (bots that only send spoken: true, never unspoken).\n const advanced =\n parts.length > 0 &&\n applySpokenBotOutputProgress(messageState, parts, text);\n\n if (!advanced) {\n // No unspoken content to advance: add this text as a part already fully spoken\n const isDefaultType =\n aggregatedBy === \"sentence\" ||\n aggregatedBy === \"word\" ||\n !aggregatedBy;\n const defaultDisplayMode = isDefaultType ? \"inline\" : undefined;\n const newPart: ConversationMessagePart = {\n text,\n final: false,\n createdAt: now.toISOString(),\n aggregatedBy,\n displayMode: defaultDisplayMode,\n };\n parts.push(newPart);\n messageState.partFinalFlags.push(true);\n messageState.currentPartIndex = parts.length - 1;\n messageState.currentCharIndex = text.length;\n\n messages[\n lastAssistantIndex === -1 ? messages.length - 1 : lastAssistantIndex\n ] = {\n ...message,\n parts,\n };\n }\n }\n\n const processedMessages = normalizeMessagesForUI(messages);\n\n const cbs = get(messageCallbacksAtom);\n const updatedMsg =\n messages[\n lastAssistantIndex === -1 ? messages.length - 1 : lastAssistantIndex\n ];\n if (isNewMessage) {\n callCallbacks(cbs, \"onMessageCreated\", updatedMsg);\n } else {\n callCallbacks(cbs, \"onMessageUpdated\", updatedMsg);\n }\n\n set(messagesAtom, processedMessages);\n set(botOutputMessageStateAtom, botOutputMessageState);\n}\n\nexport function addFunctionCall(\n get: Getter,\n set: Setter,\n data: {\n function_name?: string;\n tool_call_id?: string;\n args?: Record<string, unknown>;\n }\n) {\n const messages = get(messagesAtom);\n\n // If a tool_call_id is provided, check for an existing entry to avoid duplicates\n if (data.tool_call_id) {\n const existingIndex = findLastIndex(messages,\n (msg) =>\n msg.role === \"function_call\" &&\n msg.functionCall?.tool_call_id === data.tool_call_id\n );\n if (existingIndex !== -1) return;\n }\n\n const now = new Date();\n const message: ConversationMessage = {\n role: \"function_call\",\n final: false,\n parts: [],\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n functionCall: {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n args: data.args,\n status: \"started\",\n },\n };\n\n const updatedMessages = [...messages, message];\n const processedMessages = normalizeMessagesForUI(updatedMessages);\n callCallbacks(get(messageCallbacksAtom), \"onMessageCreated\", message);\n set(messagesAtom, processedMessages);\n}\n\nexport function updateFunctionCall(\n get: Getter,\n set: Setter,\n tool_call_id: string,\n updates: Partial<\n Pick<\n FunctionCallData,\n \"status\" | \"result\" | \"cancelled\" | \"args\" | \"function_name\" | \"tool_call_id\"\n >\n >\n): boolean {\n const messages = [...get(messagesAtom)];\n const index = findLastIndex(messages,\n (msg) =>\n msg.role === \"function_call\" &&\n msg.functionCall?.tool_call_id === tool_call_id\n );\n if (index === -1) return false;\n\n const existing = messages[index];\n const updated: ConversationMessage = {\n ...existing,\n updatedAt: new Date().toISOString(),\n final: updates.status === \"completed\" ? true : existing.final,\n functionCall: {\n ...existing.functionCall!,\n ...updates,\n },\n };\n messages[index] = updated;\n\n const processedMessages = normalizeMessagesForUI(messages);\n callCallbacks(get(messageCallbacksAtom), \"onMessageUpdated\", updated);\n set(messagesAtom, processedMessages);\n return true;\n}\n\n/**\n * Update the most recent function call message that has status \"started\"\n * and no tool_call_id yet. Used when transitioning from Started → InProgress.\n */\nexport function updateLastStartedFunctionCall(\n get: Getter,\n set: Setter,\n updates: Partial<\n Pick<FunctionCallData, \"status\" | \"tool_call_id\" | \"args\" | \"function_name\">\n >\n): boolean {\n const messages = [...get(messagesAtom)];\n const index = findLastIndex(messages,\n (msg) =>\n msg.role === \"function_call\" &&\n msg.functionCall?.status === \"started\" &&\n !msg.functionCall?.tool_call_id\n );\n if (index === -1) return false;\n\n const existing = messages[index];\n const updated: ConversationMessage = {\n ...existing,\n updatedAt: new Date().toISOString(),\n functionCall: {\n ...existing.functionCall!,\n ...updates,\n },\n };\n messages[index] = updated;\n\n const processedMessages = normalizeMessagesForUI(messages);\n callCallbacks(get(messageCallbacksAtom), \"onMessageUpdated\", updated);\n set(messagesAtom, processedMessages);\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// High-level function call lifecycle handlers\n// ---------------------------------------------------------------------------\n\nexport function handleFunctionCallStarted(\n get: Getter,\n set: Setter,\n data: { function_name?: string }\n) {\n const messages = get(messagesAtom);\n const lastFc = findLast(messages,\n (m: ConversationMessage) => m.role === \"function_call\"\n );\n\n // Check if InProgress already created an entry (events arrived out of order).\n if (\n lastFc?.functionCall &&\n lastFc.functionCall.status !== \"started\" &&\n Date.now() - new Date(lastFc.createdAt).getTime() < 2000\n ) {\n if (\n data.function_name &&\n !lastFc.functionCall.function_name &&\n lastFc.functionCall.tool_call_id\n ) {\n updateFunctionCall(get, set, lastFc.functionCall.tool_call_id, {\n function_name: data.function_name,\n });\n }\n return;\n }\n\n addFunctionCall(get, set, { function_name: data.function_name });\n}\n\nexport function handleFunctionCallInProgress(\n get: Getter,\n set: Setter,\n data: {\n function_name?: string;\n tool_call_id: string;\n args?: Record<string, unknown>;\n }\n) {\n // Tier 1: Try to update the last \"started\" entry (from LLMFunctionCallStarted)\n const updated = updateLastStartedFunctionCall(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n args: data.args,\n status: \"in_progress\",\n });\n\n if (!updated) {\n // Tier 2: Try updating an existing entry by tool_call_id\n const found = updateFunctionCall(get, set, data.tool_call_id, {\n function_name: data.function_name,\n args: data.args,\n status: \"in_progress\",\n });\n\n if (!found) {\n // Tier 3: No existing entry at all; create a new one as in_progress\n addFunctionCall(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n args: data.args,\n });\n updateFunctionCall(get, set, data.tool_call_id, {\n status: \"in_progress\",\n });\n }\n }\n}\n\nexport function handleFunctionCallStopped(\n get: Getter,\n set: Setter,\n data: {\n function_name?: string;\n tool_call_id: string;\n result?: unknown;\n cancelled?: boolean;\n }\n) {\n // Tier 1: Try updating by tool_call_id\n const found = updateFunctionCall(get, set, data.tool_call_id, {\n function_name: data.function_name,\n status: \"completed\",\n result: data.result,\n cancelled: data.cancelled,\n });\n\n if (!found) {\n // Tier 2: No match by tool_call_id (e.g. InProgress was skipped).\n const matched = updateLastStartedFunctionCall(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n });\n if (matched) {\n updateFunctionCall(get, set, data.tool_call_id, {\n status: \"completed\",\n result: data.result,\n cancelled: data.cancelled,\n });\n }\n }\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport type { ConversationMessagePart } from \"./types\";\n\nexport type BotOutputMessageCursor = {\n currentPartIndex: number;\n currentCharIndex: number;\n /**\n * Per-part: true if fully spoken OR explicitly skipped (e.g. not meant\n * to be spoken, or mismatch recovery advanced past it).\n */\n partFinalFlags: boolean[];\n};\n\nconst normalizeForMatching = (text: string): string => {\n return text.toLowerCase().replace(/[^\\w\\s]/g, \"\");\n};\n\nconst skipWhitespace = (text: string, start: number): number => {\n let i = start;\n while (i < text.length && /\\s/.test(text[i])) i++;\n return i;\n};\n\n/**\n * Finds where `spoken` appears in `unspoken`, starting from `startPosition`.\n * - Best-effort sequential word matching (normalized, punctuation-stripped)\n * - Returns the original start position on mismatch (no advancement)\n */\nconst findSpokenPositionInUnspoken = (\n spoken: string,\n unspoken: string,\n startPosition: number\n): number => {\n if (!spoken || !unspoken || startPosition >= unspoken.length) {\n return startPosition;\n }\n\n // If spoken text includes a leading separator space, skip leading whitespace in unspoken.\n let actualStart = startPosition;\n let spokenForMatching = spoken;\n if (spoken.startsWith(\" \") && startPosition < unspoken.length) {\n actualStart = skipWhitespace(unspoken, startPosition);\n spokenForMatching = spoken.trimStart();\n } else if (startPosition === 0 && startPosition < unspoken.length) {\n // If we're at the start, also skip leading whitespace (e.g. newlines)\n actualStart = skipWhitespace(unspoken, 0);\n }\n\n const remainder = unspoken.slice(actualStart);\n // Sentence-level: if spoken exactly matches the remainder (normalized), consume the whole part\n // so we never leave a word unspoken due to word-matching edge cases.\n if (\n normalizeForMatching(spokenForMatching).trim() ===\n normalizeForMatching(remainder).trim()\n ) {\n return unspoken.length;\n }\n\n const spokenWords = normalizeForMatching(spokenForMatching)\n .split(/\\s+/)\n .filter(Boolean);\n\n if (spokenWords.length === 0) return actualStart;\n\n const unspokenWords = normalizeForMatching(unspoken.slice(actualStart))\n .split(/\\s+/)\n .filter(Boolean);\n\n // Sequential match, allowing prefix match for contractions (e.g. \"I\" vs \"I'm\")\n // and limited skipping of mismatched unspoken words (e.g. punctuation artifacts).\n let matchedWords = 0;\n let consecutiveSkips = 0;\n const MAX_CONSECUTIVE_SKIPS = 2;\n for (\n let i = 0;\n i < unspokenWords.length && matchedWords < spokenWords.length;\n i++\n ) {\n const target = spokenWords[matchedWords];\n const candidate = unspokenWords[i];\n if (candidate === target || candidate.startsWith(target)) {\n matchedWords++;\n consecutiveSkips = 0;\n continue;\n }\n consecutiveSkips++;\n if (consecutiveSkips > MAX_CONSECUTIVE_SKIPS) return actualStart;\n // Skip this unspoken word and try matching the next one\n }\n\n if (matchedWords < spokenWords.length) return actualStart;\n\n // Convert word matches back into a character position in the original unspoken string.\n const isWordChar = (char: string): boolean => /[a-zA-Z0-9]/.test(char);\n let wordCount = 0;\n let i = actualStart;\n let inWord = false;\n\n while (i < unspoken.length) {\n const charIsWord = isWordChar(unspoken[i]);\n if (charIsWord && !inWord) {\n inWord = true;\n wordCount++;\n\n if (wordCount === matchedWords) {\n // Consume the rest of this word\n i++;\n while (i < unspoken.length && isWordChar(unspoken[i])) i++;\n // Include any punctuation after the word until the next space, then include the space\n while (i < unspoken.length) {\n if (unspoken[i] === \" \") {\n i++;\n break;\n }\n i++;\n }\n return i;\n }\n } else if (!charIsWord && inWord) {\n inWord = false;\n }\n i++;\n }\n\n return unspoken.length;\n};\n\n/**\n * Returns true if the cursor has not yet reached the end of all text parts,\n * meaning there is still unspoken content waiting to be spoken.\n */\nexport function hasUnspokenContent(\n cursor: BotOutputMessageCursor,\n parts: ConversationMessagePart[]\n): boolean {\n if (parts.length === 0) return false;\n\n for (let i = 0; i < parts.length; i++) {\n if (typeof parts[i]?.text !== \"string\") continue;\n if (!cursor.partFinalFlags[i]) return true;\n }\n\n return false;\n}\n\n/**\n * Advances the cursor for spoken text. Returns true if the cursor was advanced\n * (text was consumed), false if there was nothing to advance (e.g. no parts).\n * Used to detect \"spoken-only\" bots that never send unspoken events.\n */\nexport function applySpokenBotOutputProgress(\n cursor: BotOutputMessageCursor,\n parts: ConversationMessagePart[],\n spokenText: string\n): boolean {\n if (parts.length === 0) return false;\n\n // Find the next part that should be spoken (skip parts already marked final/skipped)\n let partToMatch = cursor.currentPartIndex;\n while (partToMatch < parts.length && cursor.partFinalFlags[partToMatch]) {\n partToMatch++;\n }\n if (partToMatch >= parts.length) return false;\n\n if (partToMatch > cursor.currentPartIndex) {\n cursor.currentPartIndex = partToMatch;\n cursor.currentCharIndex = 0;\n }\n\n const currentPart = parts[cursor.currentPartIndex];\n if (typeof currentPart.text !== \"string\") return false;\n\n const partText = currentPart.text;\n const startChar = cursor.currentCharIndex;\n\n const newPosition = findSpokenPositionInUnspoken(\n spokenText,\n partText,\n startChar\n );\n const whitespaceEnd = skipWhitespace(partText, startChar);\n\n if (newPosition > whitespaceEnd) {\n cursor.currentCharIndex = newPosition;\n\n if (newPosition >= partText.length) {\n cursor.partFinalFlags[cursor.currentPartIndex] = true;\n if (cursor.currentPartIndex < parts.length - 1) {\n cursor.currentPartIndex++;\n cursor.currentCharIndex = 0;\n }\n }\n return true;\n }\n\n // Intra-part scan-ahead recovery: if matching failed at the current position,\n // scan forward word-by-word within the same part. This prevents the cursor\n // from getting permanently stuck mid-part when a single word mismatch occurs\n // (e.g. TTS variation, punctuation boundary like `apexes.\"Sometimes`).\n if (startChar > 0) {\n const MAX_SCAN_WORDS = 8;\n let scanPos = startChar;\n for (let scan = 0; scan < MAX_SCAN_WORDS; scan++) {\n // Advance past current word\n while (scanPos < partText.length && !/\\s/.test(partText[scanPos]))\n scanPos++;\n // Advance past whitespace to next word\n while (scanPos < partText.length && /\\s/.test(partText[scanPos]))\n scanPos++;\n if (scanPos >= partText.length) break;\n\n const retryPos = findSpokenPositionInUnspoken(\n spokenText,\n partText,\n scanPos\n );\n const scanWsEnd = skipWhitespace(partText, scanPos);\n if (retryPos > scanWsEnd) {\n cursor.currentCharIndex = retryPos;\n if (retryPos >= partText.length) {\n cursor.partFinalFlags[cursor.currentPartIndex] = true;\n if (cursor.currentPartIndex < parts.length - 1) {\n cursor.currentPartIndex++;\n cursor.currentCharIndex = 0;\n }\n }\n return true;\n }\n }\n }\n\n // Mismatch recovery: try to find the spoken text in a later part.\n for (\n let nextPartIdx = cursor.currentPartIndex + 1;\n nextPartIdx < parts.length;\n nextPartIdx++\n ) {\n const nextPart = parts[nextPartIdx];\n if (typeof nextPart.text !== \"string\") continue;\n\n const match = findSpokenPositionInUnspoken(spokenText, nextPart.text, 0);\n const nextWhitespaceEnd = skipWhitespace(nextPart.text, 0);\n if (match > nextWhitespaceEnd) {\n // Mark skipped parts as final and jump to the matched part\n for (let i = cursor.currentPartIndex; i < nextPartIdx; i++) {\n cursor.partFinalFlags[i] = true;\n }\n cursor.currentPartIndex = nextPartIdx;\n cursor.currentCharIndex = match;\n return true;\n }\n }\n\n // If we're stuck at the start, mark the current part as skipped to avoid deadlock.\n if (startChar === 0 && cursor.currentPartIndex < parts.length - 1) {\n cursor.partFinalFlags[cursor.currentPartIndex] = true;\n cursor.currentPartIndex++;\n cursor.currentCharIndex = 0;\n return true;\n }\n\n return false;\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { atom } from \"jotai\";\n\nimport type { BotOutputMessageCursor } from \"./botOutput\";\nimport type { ConversationMessage } from \"./types\";\n\n/** Raw (pre-normalization) message list */\nexport const messagesAtom = atom<ConversationMessage[]>([]);\n\n/** Tracks speech-progress cursor per message (keyed by message createdAt) */\nexport const botOutputMessageStateAtom = atom<\n Map<string, BotOutputMessageCursor>\n>(new Map());\n\n/** Callback set registered per hook instance */\nexport type MessageCallbacks = {\n onMessageCreated?: (message: ConversationMessage) => void;\n onMessageUpdated?: (message: ConversationMessage) => void;\n};\n\n/** Registered callbacks invoked on message lifecycle events */\nexport const messageCallbacksAtom = atom<Map<string, MessageCallbacks>>(\n new Map()\n);\n\n/** Whether BotOutput events are supported (RTVI 1.1.0+): null = unknown, true/false = detected */\nexport const botOutputSupportedAtom = atom<boolean | null>(null);\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\n// ES2020-compatible polyfills for findLast / findLastIndex\n\nexport function findLastIndex<T>(\n arr: T[],\n predicate: (value: T, index: number, array: T[]) => boolean\n): number {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (predicate(arr[i], i, arr)) return i;\n }\n return -1;\n}\n\nexport function findLast<T>(\n arr: T[],\n predicate: (value: T, index: number, array: T[]) => boolean\n): T | undefined {\n const idx = findLastIndex(arr, predicate);\n return idx === -1 ? undefined : arr[idx];\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport {\n BotOutputData,\n BotReadyData,\n type LLMFunctionCallInProgressData,\n type LLMFunctionCallStartedData,\n type LLMFunctionCallStoppedData,\n RTVIEvent,\n} from \"@pipecat-ai/client-js\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport { useRTVIClientEvent } from \"../useRTVIClientEvent\";\nimport { hasUnspokenContent } from \"./botOutput\";\nimport {\n addMessage,\n clearMessages,\n finalizeLastMessage,\n handleFunctionCallInProgress,\n handleFunctionCallStarted,\n handleFunctionCallStopped,\n removeEmptyLastMessage,\n updateAssistantBotOutput,\n updateLastMessage,\n upsertUserTranscript,\n} from \"./conversationActions\";\nimport {\n botOutputMessageStateAtom,\n botOutputSupportedAtom,\n messagesAtom,\n} from \"./conversationAtoms\";\nimport type { ConversationMessage } from \"./types\";\nimport { findLast, findLastIndex } from \"./utils\";\n\n/**\n * Checks if a version meets a minimum version requirement.\n * Inlined to avoid adding a `semver` dependency.\n */\nfunction isMinVersion(\n currentVersion: string,\n minVersion: [number, number, number]\n): boolean {\n // Strip pre-release suffix (e.g. \"1.1.0-beta.1\" -> \"1.1.0\")\n const parts = currentVersion.split(\"-\")[0].split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((parts[i] || 0) > minVersion[i]) return true;\n if ((parts[i] || 0) < minVersion[i]) return false;\n }\n return true; // equal\n}\n\n/** Delay (ms) before finalizing the assistant message after bot stops speaking. */\nconst BOT_STOPPED_FINALIZE_DELAY_MS = 2500;\n\n/**\n * Internal hook that wires RTVI events to conversation state atoms.\n * Called once inside PipecatConversationProvider.\n */\nexport function useConversationEventWiring() {\n const userStoppedTimeout = useRef<ReturnType<typeof setTimeout>>(undefined);\n const botStoppedSpeakingTimeoutRef =\n useRef<ReturnType<typeof setTimeout>>(undefined);\n const assistantStreamResetRef = useRef<number>(0);\n const botOutputLastChunkRef = useRef<{ spoken: string; unspoken: string }>({\n spoken: \"\",\n unspoken: \"\",\n });\n\n // Clean up pending timeouts on unmount\n useEffect(() => {\n return () => {\n clearTimeout(userStoppedTimeout.current);\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n };\n }, []);\n\n // -- helpers ---------------------------------------------------------------\n\n const finalizeLastAssistantMessageIfPending = useAtomCallback(\n useCallback((get, set) => {\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n botStoppedSpeakingTimeoutRef.current = undefined;\n const messages = get(messagesAtom);\n const lastAssistant = findLast(messages,\n (m: ConversationMessage) => m.role === \"assistant\"\n );\n if (lastAssistant && !lastAssistant.final) {\n finalizeLastMessage(get, set, \"assistant\");\n }\n }, [])\n );\n\n const ensureAssistantMessage = useAtomCallback(\n useCallback((get, set) => {\n const messages = get(messagesAtom);\n const lastAssistantIndex = findLastIndex(messages,\n (msg: ConversationMessage) => msg.role === \"assistant\"\n );\n const lastAssistant =\n lastAssistantIndex !== -1 ? messages[lastAssistantIndex] : undefined;\n\n if (!lastAssistant || lastAssistant.final) {\n // If the message was finalized but still has unspoken content, it was\n // finalized prematurely (e.g. BotStoppedSpeaking timer fired during a\n // TTS pause mid-response). Un-finalize it instead of creating a new\n // message bubble — but only when no user message followed.\n if (\n lastAssistant?.final &&\n lastAssistantIndex === messages.length - 1\n ) {\n const messageId = lastAssistant.createdAt;\n const botOutputState = get(botOutputMessageStateAtom);\n const cursor = botOutputState.get(messageId);\n if (\n cursor &&\n hasUnspokenContent(cursor, lastAssistant.parts || [])\n ) {\n updateLastMessage(get, set, \"assistant\", { final: false });\n return false;\n }\n }\n\n addMessage(get, set, {\n role: \"assistant\",\n final: false,\n parts: [],\n });\n assistantStreamResetRef.current += 1;\n return true;\n }\n return false;\n }, [])\n );\n\n // -- event handlers --------------------------------------------------------\n\n useRTVIClientEvent(\n RTVIEvent.Connected,\n useAtomCallback(\n useCallback((get, set) => {\n clearMessages(get, set);\n set(botOutputSupportedAtom, null);\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n botStoppedSpeakingTimeoutRef.current = undefined;\n botOutputLastChunkRef.current = { spoken: \"\", unspoken: \"\" };\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.BotReady,\n useAtomCallback(\n useCallback((_get, set, botData: BotReadyData) => {\n const rtviVersion = botData.version;\n const supportsBotOutput = isMinVersion(rtviVersion, [1, 1, 0]);\n set(botOutputSupportedAtom, supportsBotOutput);\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.BotOutput,\n useAtomCallback(\n useCallback(\n (get, set, data: BotOutputData) => {\n // A BotOutput event means the response is still active; cancel any\n // pending finalize timer from BotStoppedSpeaking.\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n botStoppedSpeakingTimeoutRef.current = undefined;\n\n ensureAssistantMessage();\n\n // Handle spacing for BotOutput chunks\n let textToAdd = data.text;\n const lastChunk = data.spoken\n ? botOutputLastChunkRef.current.spoken\n : botOutputLastChunkRef.current.unspoken;\n\n // Add space separator if needed between BotOutput chunks\n if (lastChunk) {\n textToAdd = \" \" + textToAdd;\n }\n\n // Update the appropriate last chunk tracker\n if (data.spoken) {\n botOutputLastChunkRef.current.spoken = textToAdd;\n } else {\n botOutputLastChunkRef.current.unspoken = textToAdd;\n }\n\n // Update both spoken and unspoken text streams\n const isFinal = data.aggregated_by === \"sentence\";\n updateAssistantBotOutput(\n get,\n set,\n textToAdd,\n isFinal,\n data.spoken,\n data.aggregated_by\n );\n },\n [ensureAssistantMessage]\n )\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.BotStoppedSpeaking,\n useAtomCallback(\n useCallback((get, set) => {\n // Don't finalize immediately; start a timer. Bot may start speaking again (pause).\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n const messages = get(messagesAtom);\n const lastAssistant = findLast(messages,\n (m: ConversationMessage) => m.role === \"assistant\"\n );\n if (!lastAssistant || lastAssistant.final) return;\n botStoppedSpeakingTimeoutRef.current = setTimeout(() => {\n botStoppedSpeakingTimeoutRef.current = undefined;\n\n // Snap the speech-progress cursor to the end of all parts.\n // The bot finished speaking normally (not interrupted), so all\n // text should render as \"spoken\". Without this, text from the\n // last sentence can remain grey if the spoken BotOutput event\n // didn't match the unspoken text exactly.\n const msgs = get(messagesAtom);\n const cursorMap = new Map(get(botOutputMessageStateAtom));\n const last = findLast(msgs,\n (m: ConversationMessage) => m.role === \"assistant\"\n );\n if (last) {\n const cursor = cursorMap.get(last.createdAt);\n if (cursor && last.parts && last.parts.length > 0) {\n const lastPartIdx = last.parts.length - 1;\n const lastPartText = last.parts[lastPartIdx]?.text;\n cursor.currentPartIndex = lastPartIdx;\n cursor.currentCharIndex =\n typeof lastPartText === \"string\" ? lastPartText.length : 0;\n for (let i = 0; i <= lastPartIdx; i++) {\n cursor.partFinalFlags[i] = true;\n }\n set(botOutputMessageStateAtom, cursorMap);\n }\n }\n\n finalizeLastMessage(get, set, \"assistant\");\n }, BOT_STOPPED_FINALIZE_DELAY_MS);\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.BotStartedSpeaking,\n useCallback(() => {\n // Bot is speaking again; reset the finalize timer (bot was just pausing).\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n botStoppedSpeakingTimeoutRef.current = undefined;\n }, [])\n );\n\n useRTVIClientEvent(\n RTVIEvent.UserStartedSpeaking,\n useAtomCallback(\n useCallback(\n (get, set) => {\n // User started a new turn; bot's turn is done. Fast-forward: finalize immediately.\n finalizeLastAssistantMessageIfPending();\n clearTimeout(userStoppedTimeout.current);\n\n // Only finalize the previous user message if the bot has responded since\n // the user last spoke. This prevents finalizing during VAD gaps (brief\n // breathing pauses within the same user turn where UserStoppedSpeaking/\n // UserStartedSpeaking fire without an actual turn change).\n const messages = get(messagesAtom);\n const lastUserIdx = findLastIndex(\n messages,\n (m: ConversationMessage) => m.role === \"user\"\n );\n if (lastUserIdx !== -1 && !messages[lastUserIdx].final) {\n const hasBotActivityAfterUser = messages\n .slice(lastUserIdx + 1)\n .some((m: ConversationMessage) => m.role === \"assistant\");\n if (hasBotActivityAfterUser) {\n finalizeLastMessage(get, set, \"user\");\n }\n }\n },\n [finalizeLastAssistantMessageIfPending]\n )\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.UserTranscript,\n useAtomCallback(\n useCallback((get, set, data) => {\n const text = data.text ?? \"\";\n const final = Boolean(data.final);\n upsertUserTranscript(get, set, text, final);\n\n // If we got any transcript, cancel pending cleanup\n clearTimeout(userStoppedTimeout.current);\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.UserStoppedSpeaking,\n useAtomCallback(\n useCallback((get, set) => {\n clearTimeout(userStoppedTimeout.current);\n // If no transcript ends up arriving, ensure any accidental empty placeholder is removed.\n userStoppedTimeout.current = setTimeout(() => {\n // Re-read state at timeout time\n const messages = get(messagesAtom);\n const lastUser = findLast(messages,\n (m: ConversationMessage) => m.role === \"user\"\n );\n const hasParts =\n Array.isArray(lastUser?.parts) && lastUser!.parts.length > 0;\n if (!lastUser || !hasParts) {\n removeEmptyLastMessage(get, set, \"user\");\n } else if (!lastUser.final) {\n finalizeLastMessage(get, set, \"user\");\n }\n }, 3000);\n }, [])\n )\n );\n\n // LLM Function Call lifecycle events\n useRTVIClientEvent(\n RTVIEvent.LLMFunctionCallStarted,\n useAtomCallback(\n useCallback((get, set, data: LLMFunctionCallStartedData) => {\n handleFunctionCallStarted(get, set, {\n function_name: data.function_name,\n });\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.LLMFunctionCallInProgress,\n useAtomCallback(\n useCallback((get, set, data: LLMFunctionCallInProgressData) => {\n handleFunctionCallInProgress(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n args: data.arguments,\n });\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.LLMFunctionCallStopped,\n useAtomCallback(\n useCallback((get, set, data: LLMFunctionCallStoppedData) => {\n handleFunctionCallStopped(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n result: data.result,\n cancelled: data.cancelled,\n });\n }, [])\n )\n );\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, RTVIEventHandler } from \"@pipecat-ai/client-js\";\nimport { useContext, useEffect } from \"react\";\n\nimport { RTVIEventContext } from \"./RTVIEventContext\";\n\nexport const useRTVIClientEvent = <E extends RTVIEvent>(\n event: E,\n handler: RTVIEventHandler<E>\n) => {\n const { on, off } = useContext(RTVIEventContext);\n\n useEffect(() => {\n on(event, handler);\n return () => {\n off(event, handler);\n };\n }, [event, handler, on, off]);\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\nimport { RTVIEvent, RTVIEventHandler } from \"@pipecat-ai/client-js\";\nimport { createContext } from \"react\";\n\nexport const RTVIEventContext = createContext<{\n on: <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => void;\n off: <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => void;\n}>({\n on: () => {},\n off: () => {},\n});\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, TransportState } from \"@pipecat-ai/client-js\";\nimport React, { createContext, useCallback, useState } from \"react\";\n\nimport { usePipecatClient } from \"./usePipecatClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\nexport const PipecatClientCamStateContext = createContext<{\n enableCam: (enabled: boolean) => void;\n isCamEnabled: boolean;\n}>({\n enableCam: () => {\n throw new Error(\n \"PipecatClientCamStateContext: enableCam() called outside of provider\"\n );\n },\n isCamEnabled: false,\n});\nexport const PipecatClientMicStateContext = createContext<{\n enableMic: (enabled: boolean) => void;\n isMicEnabled: boolean;\n}>({\n enableMic: () => {\n throw new Error(\n \"PipecatClientMicStateContext: enableMic() called outside of provider\"\n );\n },\n isMicEnabled: false,\n});\nexport const PipecatClientScreenShareStateContext = createContext<{\n enableScreenShare: (enabled: boolean) => void;\n isScreenShareEnabled: boolean;\n}>({\n enableScreenShare: () => {\n throw new Error(\n \"PipecatClientScreenShareStateContext: enableScreenShare() called outside of provider\"\n );\n },\n isScreenShareEnabled: false,\n});\nexport const PipecatClientTransportStateContext =\n createContext<TransportState>(\"disconnected\");\n\nexport const PipecatClientStateProvider: React.FC<React.PropsWithChildren> = ({\n children,\n}) => {\n const client = usePipecatClient();\n const [isCamEnabled, setIsCamEnabled] = useState(false);\n const [isMicEnabled, setIsMicEnabled] = useState(false);\n const [isScreenShareEnabled, setIsScreenShareEnabled] = useState(false);\n const [transportState, setTransportState] =\n useState<TransportState>(\"disconnected\");\n\n useRTVIClientEvent(RTVIEvent.TransportStateChanged, (state) => {\n setTransportState(state);\n if (state === \"initialized\" && client) {\n setIsCamEnabled(client.isCamEnabled ?? false);\n setIsMicEnabled(client.isMicEnabled ?? false);\n setIsScreenShareEnabled(client.isSharingScreen ?? false);\n }\n });\n\n const enableCam = useCallback(\n (enabled: boolean) => {\n setIsCamEnabled(enabled);\n client?.enableCam?.(enabled);\n },\n [client]\n );\n\n const enableMic = useCallback(\n (enabled: boolean) => {\n setIsMicEnabled(enabled);\n client?.enableMic?.(enabled);\n },\n [client]\n );\n\n const enableScreenShare = useCallback(\n (enabled: boolean) => {\n client?.enableScreenShare?.(enabled);\n },\n [client]\n );\n\n useRTVIClientEvent(RTVIEvent.ScreenTrackStarted, (_track, participant) => {\n if (participant?.local) {\n setIsScreenShareEnabled(true);\n }\n });\n\n useRTVIClientEvent(RTVIEvent.ScreenTrackStopped, (_track, participant) => {\n if (participant?.local) {\n setIsScreenShareEnabled(false);\n }\n });\n\n return (\n <PipecatClientTransportStateContext.Provider value={transportState}>\n <PipecatClientCamStateContext.Provider\n value={{ enableCam, isCamEnabled }}\n >\n <PipecatClientMicStateContext.Provider\n value={{ enableMic, isMicEnabled }}\n >\n <PipecatClientScreenShareStateContext.Provider\n value={{ enableScreenShare, isScreenShareEnabled }}\n >\n {children}\n </PipecatClientScreenShareStateContext.Provider>\n </PipecatClientMicStateContext.Provider>\n </PipecatClientCamStateContext.Provider>\n </PipecatClientTransportStateContext.Provider>\n );\n};\n","import React, { useCallback } from \"react\";\n\nimport { usePipecatClientCamControl } from \"./usePipecatClientCamControl\";\n\nexport interface PipecatClientCamToggleProps {\n /**\n * Callback fired when camera state changes\n */\n onCamEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the cam toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isCamEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling camera state\n */\nexport const PipecatClientCamToggle: React.FC<PipecatClientCamToggleProps> = ({\n onCamEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { isCamEnabled, enableCam } = usePipecatClientCamControl();\n\n const handleToggleCam = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isCamEnabled;\n enableCam(newEnabledState);\n onCamEnabledChanged?.(newEnabledState);\n }, [disabled, enableCam, isCamEnabled, onCamEnabledChanged]);\n\n return (\n <>\n {children({\n isCamEnabled,\n onClick: handleToggleCam,\n disabled,\n })}\n </>\n );\n};\n\nexport default PipecatClientCamToggle;\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\nimport { useContext } from \"react\";\n\nimport { PipecatClientCamStateContext } from \"./PipecatClientState\";\n\n/**\n * Hook to control camera state\n */\nexport const usePipecatClientCamControl = () =>\n useContext(PipecatClientCamStateContext);\n","import React, { useCallback } from \"react\";\n\nimport { usePipecatClientMicControl } from \"./usePipecatClientMicControl\";\n\nexport interface PipecatClientMicToggleProps {\n /**\n * Callback fired when microphone state changes\n */\n onMicEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the mic toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isMicEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling microphone state\n */\nexport const PipecatClientMicToggle: React.FC<PipecatClientMicToggleProps> = ({\n onMicEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { enableMic, isMicEnabled } = usePipecatClientMicControl();\n\n const handleToggleMic = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isMicEnabled;\n enableMic(newEnabledState);\n onMicEnabledChanged?.(newEnabledState);\n }, [disabled, enableMic, isMicEnabled, onMicEnabledChanged]);\n\n return (\n <>\n {children({\n isMicEnabled,\n onClick: handleToggleMic,\n disabled,\n })}\n </>\n );\n};\n\nexport default PipecatClientMicToggle;\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { PipecatClientMicStateContext } from \"./PipecatClientState\";\n\n/**\n * Hook to control microphone state\n */\nexport const usePipecatClientMicControl = () =>\n useContext(PipecatClientMicStateContext);\n","/**\n * Copyright (c) 2025, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { useCallback, useEffect } from \"react\";\n\nimport { usePipecatClientScreenShareControl } from \"./usePipecatClientScreenShareControl\";\n\nexport interface PipecatClientScreenShareToggleProps {\n /**\n * Callback when screen share state changes\n */\n onScreenShareEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the screen share toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isScreenShareEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling screen share state\n */\nexport const PipecatClientScreenShareToggle: React.FC<\n PipecatClientScreenShareToggleProps\n> = ({ onScreenShareEnabledChanged, disabled = false, children }) => {\n const { enableScreenShare, isScreenShareEnabled } =\n usePipecatClientScreenShareControl();\n\n const handleToggleScreenShare = useCallback(() => {\n if (disabled) return;\n enableScreenShare(!isScreenShareEnabled);\n }, [disabled, enableScreenShare, isScreenShareEnabled]);\n\n useEffect(() => {\n onScreenShareEnabledChanged?.(isScreenShareEnabled);\n }, [isScreenShareEnabled, onScreenShareEnabledChanged]);\n\n return (\n <>\n {children({\n isScreenShareEnabled,\n onClick: handleToggleScreenShare,\n disabled,\n })}\n </>\n );\n};\n\nexport default PipecatClientScreenShareToggle;\n","/**\n * Copyright (c) 2025, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { PipecatClientScreenShareStateContext } from \"./PipecatClientState\";\n\n/**\n * Hook to control screen share state using React Context\n * This provides a simpler interface for basic screen share control\n * For more advanced state management with Jotai atoms, use usePipecatClientScreenShare\n */\nexport const usePipecatClientScreenShareControl = () =>\n useContext(PipecatClientScreenShareStateContext);\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { forwardRef, useEffect, useRef } from \"react\";\n\nimport useMergedRef from \"./useMergedRef\";\nimport { usePipecatClientMediaTrack } from \"./usePipecatClientMediaTrack\";\n\ninterface PipecatClientVideoInterface {\n aspectRatio: number;\n height: number;\n width: number;\n}\n\nexport interface Props extends Omit<\n React.VideoHTMLAttributes<HTMLVideoElement>,\n \"onResize\"\n> {\n participant: \"local\" | \"bot\";\n\n /**\n * Defines the video track type to display. Default: 'video'.\n */\n trackType?: \"screenVideo\" | \"video\";\n\n /**\n * Defines whether the video should be fully contained or cover the box. Default: 'contain'.\n */\n fit?: \"contain\" | \"cover\";\n /**\n * Forces the video to be mirrored, if set.\n */\n mirror?: boolean;\n\n /**\n * Optional callback, which is triggered whenever the video's rendered width or height changes.\n * Returns the video's native width, height and aspectRatio.\n */\n onResize?(dimensions: PipecatClientVideoInterface): void;\n}\n\nexport const PipecatClientVideo = forwardRef<HTMLVideoElement, Props>(\n function VoiceClientVideo(\n {\n participant = \"local\",\n fit = \"contain\",\n mirror,\n onResize,\n style = {},\n trackType = \"video\",\n ...props\n },\n ref\n ) {\n const videoTrack: MediaStreamTrack | null = usePipecatClientMediaTrack(\n trackType,\n participant\n );\n\n const videoEl = useRef<HTMLVideoElement>(null);\n const videoRef = useMergedRef<HTMLVideoElement>(videoEl, ref);\n\n /**\n * Handle canplay & picture-in-picture events.\n */\n useEffect(function setupVideoEvents() {\n const video = videoEl.current;\n if (!video) return;\n\n const playVideo = () => {\n const promise = video.play();\n if (promise !== undefined) {\n promise\n .then(() => {\n // All good, playback started.\n video.controls = false;\n })\n .catch((error) => {\n // Auto-play was prevented. Show video controls, so user can play video manually.\n video.controls = true;\n console.warn(\"Failed to play video\", error);\n });\n }\n };\n\n const handleCanPlay = () => {\n if (!video.paused) return;\n playVideo();\n };\n const handleEnterPIP = () => {\n video.style.transform = \"scale(1)\";\n };\n const handleLeavePIP = () => {\n video.style.transform = \"\";\n setTimeout(() => {\n if (video.paused) playVideo();\n }, 100);\n };\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") return;\n if (!video.paused) return;\n playVideo();\n };\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.addEventListener(\"leavepictureinpicture\", handleLeavePIP);\n\n // Videos can be paused if media was played in another app on iOS.\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n return () => {\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.removeEventListener(\"leavepictureinpicture\", handleLeavePIP);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n };\n }, []);\n\n /**\n * Update srcObject.\n */\n useEffect(\n function updateSrcObject() {\n const video = videoEl.current;\n if (!video || !videoTrack) return;\n video.srcObject = new MediaStream([videoTrack]);\n video.load();\n return () => {\n // clean up when unmounted\n video.srcObject = null;\n video.load();\n };\n },\n [videoTrack, videoTrack?.id]\n );\n\n /**\n * Add optional event listener for resize event so the parent component\n * can know the video's native aspect ratio.\n */\n useEffect(\n function reportVideoDimensions() {\n const video = videoEl.current;\n if (!onResize || !video) return;\n\n let frame: ReturnType<typeof requestAnimationFrame>;\n function handleResize() {\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n const video = videoEl.current;\n if (!video || document.hidden) return;\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n if (videoWidth && videoHeight) {\n onResize?.({\n aspectRatio: videoWidth / videoHeight,\n height: videoHeight,\n width: videoWidth,\n });\n }\n });\n }\n\n handleResize();\n video.addEventListener(\"loadedmetadata\", handleResize);\n video.addEventListener(\"resize\", handleResize);\n\n return () => {\n if (frame) cancelAnimationFrame(frame);\n video.removeEventListener(\"loadedmetadata\", handleResize);\n video.removeEventListener(\"resize\", handleResize);\n };\n },\n [onResize]\n );\n\n return (\n <video\n autoPlay\n muted\n playsInline\n ref={videoRef}\n style={{\n objectFit: fit,\n transform: mirror ? \"scale(-1, 1)\" : \"\",\n ...style,\n }}\n {...props}\n />\n );\n }\n);\nPipecatClientVideo.displayName = \"PipecatClientVideo\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n *\n * This file contains code derived from:\n * https://github.com/jaredLunde/react-hook/blob/master/packages/merged-ref/src/index.tsx\n * Original author: Jared Lunde (https://github.com/jaredLunde)\n * Original license: MIT (https://github.com/jaredLunde/react-hook/blob/master/LICENSE)\n */\n\nimport React, { useCallback } from \"react\";\n\nfunction useMergedRef<T>(...refs: React.Ref<T>[]): React.RefCallback<T> {\n return useCallback(\n (element: T) => {\n for (let i = 0; i < refs.length; i++) {\n const ref = refs[i];\n if (typeof ref === \"function\") ref(element);\n else if (ref && typeof ref === \"object\")\n (ref as React.MutableRefObject<T>).current = element;\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n refs\n );\n}\n\nexport default useMergedRef;\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\nimport { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { usePipecatClient } from \"./usePipecatClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype OptionalMediaDeviceInfo = MediaDeviceInfo | Record<string, never>;\n\nconst availableMicsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableCamsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableSpeakersAtom = atom<MediaDeviceInfo[]>([]);\nconst selectedMicAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedCamAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedSpeakerAtom = atom<OptionalMediaDeviceInfo>({});\n\nexport const usePipecatClientMediaDevices = () => {\n const client = usePipecatClient();\n\n const availableCams = useAtomValue(availableCamsAtom);\n const availableMics = useAtomValue(availableMicsAtom);\n const availableSpeakers = useAtomValue(availableSpeakersAtom);\n const selectedCam = useAtomValue(selectedCamAtom);\n const selectedMic = useAtomValue(selectedMicAtom);\n const selectedSpeaker = useAtomValue(selectedSpeakerAtom);\n\n const initDevices = useAtomCallback(\n useCallback(\n async (_get, set) => {\n if (!client) return;\n\n const availableCams = await client.getAllCams();\n const availableMics = await client.getAllMics();\n const availableSpeakers = await client.getAllSpeakers();\n\n set(availableCamsAtom, availableCams);\n set(availableMicsAtom, availableMics);\n set(availableSpeakersAtom, availableSpeakers);\n\n set(selectedCamAtom, client.selectedCam);\n set(selectedMicAtom, client.selectedMic);\n set(selectedSpeakerAtom, client.selectedSpeaker);\n },\n [client]\n )\n );\n\n useEffect(() => {\n initDevices();\n }, [initDevices]);\n\n useRTVIClientEvent(\n RTVIEvent.AvailableCamsUpdated,\n useAtomCallback(\n useCallback((_get, set, cams) => {\n set(availableCamsAtom, cams);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableMicsUpdated,\n useAtomCallback(\n useCallback((_get, set, mics) => {\n set(availableMicsAtom, mics);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableSpeakersUpdated,\n useAtomCallback(\n useCallback((_get, set, speakers) => {\n set(availableSpeakersAtom, speakers);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.CamUpdated,\n useAtomCallback(\n useCallback((_get, set, cam) => {\n set(selectedCamAtom, cam);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.MicUpdated,\n useAtomCallback(\n useCallback((_get, set, mic) => {\n set(selectedMicAtom, mic);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useAtomCallback(\n useCallback((_get, set, speaker) => {\n set(selectedSpeakerAtom, speaker);\n }, [])\n )\n );\n\n const updateCam = useCallback(\n (id: string) => {\n client?.updateCam(id);\n },\n [client]\n );\n const updateMic = useCallback(\n (id: string) => {\n client?.updateMic(id);\n },\n [client]\n );\n const updateSpeaker = useCallback(\n (id: string) => {\n client?.updateSpeaker(id);\n },\n [client]\n );\n\n return {\n availableCams,\n availableMics,\n availableSpeakers,\n selectedCam,\n selectedMic,\n selectedSpeaker,\n updateCam,\n updateMic,\n updateSpeaker,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { PipecatClientTransportStateContext } from \"./PipecatClientState\";\n\nexport const usePipecatClientTransportState = () =>\n useContext(PipecatClientTransportStateContext);\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { useEffect, useRef } from \"react\";\n\nimport { usePipecatClientMediaTrack } from \"./usePipecatClientMediaTrack\";\n\ntype ParticipantType = Parameters<typeof usePipecatClientMediaTrack>[1];\n\ninterface Props {\n backgroundColor?: string;\n barColor?: string;\n barCount?: number;\n barGap?: number;\n barLineCap?: \"round\" | \"square\";\n barMaxHeight?: number;\n barOrigin?: \"top\" | \"bottom\" | \"center\";\n barWidth?: number;\n participantType: ParticipantType;\n}\n\nexport const VoiceVisualizer: React.FC<Props> = React.memo(\n ({\n backgroundColor = \"transparent\",\n barColor = \"black\",\n barCount = 5,\n barGap = 12,\n barLineCap = \"round\",\n barMaxHeight = 120,\n barOrigin = \"center\",\n barWidth = 30,\n participantType,\n }) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const track: MediaStreamTrack | null = usePipecatClientMediaTrack(\n \"audio\",\n participantType\n );\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const canvasWidth = barCount * barWidth + (barCount - 1) * barGap;\n const canvasHeight = barMaxHeight;\n\n const canvas = canvasRef.current;\n\n const scaleFactor = 2;\n\n // Make canvas fill the width and height of its container\n const resizeCanvas = () => {\n canvas.width = canvasWidth * scaleFactor;\n canvas.height = canvasHeight * scaleFactor;\n\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n\n canvasCtx.lineCap = barLineCap;\n canvasCtx.scale(scaleFactor, scaleFactor);\n };\n\n const canvasCtx = canvas.getContext(\"2d\")!;\n resizeCanvas();\n\n if (!track) return;\n\n const audioContext = new AudioContext();\n const source = audioContext.createMediaStreamSource(\n new MediaStream([track])\n );\n const analyser = audioContext.createAnalyser();\n\n analyser.fftSize = 1024;\n\n source.connect(analyser);\n\n const frequencyData = new Uint8Array(analyser.frequencyBinCount);\n\n canvasCtx.lineCap = barLineCap;\n\n // Create frequency bands based on barCount\n const bands = Array.from({ length: barCount }, (_, i) => {\n // Use improved logarithmic scale for better frequency distribution\n const minFreq = barCount > 20 ? 200 : 80; // Adjust min frequency based on bar count\n const maxFreq = 10000; // Cover most important audio frequencies\n\n // Use Mel scale inspired approach for more perceptually uniform distribution\n // This helps with a large number of bars by placing fewer in the very low range\n // https://en.wikipedia.org/wiki/Mel_scale\n const melMin = 2595 * Math.log10(1 + minFreq / 700);\n const melMax = 2595 * Math.log10(1 + maxFreq / 700);\n const melStep = (melMax - melMin) / barCount;\n\n const melValue = melMin + i * melStep;\n const startFreq = 700 * (Math.pow(10, melValue / 2595) - 1);\n const endFreq = 700 * (Math.pow(10, (melValue + melStep) / 2595) - 1);\n\n return {\n startFreq,\n endFreq,\n smoothValue: 0,\n };\n });\n\n const getFrequencyBinIndex = (frequency: number) => {\n const nyquist = audioContext.sampleRate / 2;\n return Math.round(\n (frequency / nyquist) * (analyser.frequencyBinCount - 1)\n );\n };\n\n function drawSpectrum() {\n analyser.getByteFrequencyData(frequencyData);\n canvasCtx.clearRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n canvasCtx.fillStyle = backgroundColor;\n canvasCtx.fillRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n\n let isActive = false;\n\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2; // Center bars\n\n const adjustedCircleRadius = barWidth / 2; // Fixed radius for reset circles\n\n bands.forEach((band, i) => {\n const startIndex = getFrequencyBinIndex(band.startFreq);\n const endIndex = getFrequencyBinIndex(band.endFreq);\n const bandData = frequencyData.slice(startIndex, endIndex);\n const bandValue =\n bandData.reduce((acc, val) => acc + val, 0) / bandData.length;\n\n const smoothingFactor = 0.2;\n\n if (bandValue < 1) {\n band.smoothValue = Math.max(\n band.smoothValue - smoothingFactor * 5,\n 0\n );\n } else {\n band.smoothValue =\n band.smoothValue +\n (bandValue - band.smoothValue) * smoothingFactor;\n isActive = true;\n }\n\n const x = startX + i * (barWidth + barGap);\n // Calculate bar height with a maximum cap\n const minHeight = 0;\n const barHeight = Math.max(\n minHeight,\n Math.min((band.smoothValue / 255) * barMaxHeight, barMaxHeight)\n );\n\n let yTop, yBottom;\n const canvasHeight = canvas.height / scaleFactor;\n\n switch (barOrigin) {\n case \"top\":\n yTop = adjustedCircleRadius;\n yBottom = Math.min(\n adjustedCircleRadius + barHeight,\n canvasHeight - adjustedCircleRadius\n );\n break;\n case \"bottom\":\n yBottom = canvasHeight - adjustedCircleRadius;\n yTop = Math.max(yBottom - barHeight, adjustedCircleRadius);\n break;\n case \"center\":\n default:\n yTop = Math.max(\n canvasHeight / 2 - barHeight / 2,\n adjustedCircleRadius\n );\n yBottom = Math.min(\n canvasHeight / 2 + barHeight / 2,\n canvasHeight - adjustedCircleRadius\n );\n break;\n }\n\n if (band.smoothValue > 0) {\n canvasCtx.beginPath();\n canvasCtx.moveTo(x + barWidth / 2, yTop);\n canvasCtx.lineTo(x + barWidth / 2, yBottom);\n canvasCtx.lineWidth = barWidth;\n canvasCtx.strokeStyle = barColor;\n canvasCtx.stroke();\n } else {\n drawInactiveCircle(adjustedCircleRadius, barColor, x, yTop);\n }\n });\n\n if (!isActive) {\n drawInactiveCircles(adjustedCircleRadius, barColor);\n }\n\n requestAnimationFrame(drawSpectrum);\n }\n\n function drawInactiveCircle(\n circleRadius: number,\n color: string,\n x: number,\n y: number\n ) {\n switch (barLineCap) {\n case \"square\":\n canvasCtx.fillStyle = color;\n canvasCtx.fillRect(\n x + barWidth / 2 - circleRadius,\n y - circleRadius,\n circleRadius * 2,\n circleRadius * 2\n );\n break;\n case \"round\":\n default:\n canvasCtx.beginPath();\n canvasCtx.arc(x + barWidth / 2, y, circleRadius, 0, 2 * Math.PI);\n canvasCtx.fillStyle = color;\n canvasCtx.fill();\n canvasCtx.closePath();\n break;\n }\n }\n\n function drawInactiveCircles(circleRadius: number, color: string) {\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2;\n const canvasHeight = canvas.height / scaleFactor;\n\n let y;\n switch (barOrigin) {\n case \"top\":\n y = circleRadius;\n break;\n case \"bottom\":\n y = canvasHeight - circleRadius;\n break;\n case \"center\":\n default:\n y = canvasHeight / 2;\n break;\n }\n\n bands.forEach((_, i) => {\n const x = startX + i * (barWidth + barGap);\n drawInactiveCircle(circleRadius, color, x, y);\n });\n }\n\n drawSpectrum();\n\n // Handle resizing\n window.addEventListener(\"resize\", resizeCanvas);\n\n return () => {\n audioContext.close();\n window.removeEventListener(\"resize\", resizeCanvas);\n };\n }, [\n backgroundColor,\n barColor,\n barCount,\n barGap,\n barLineCap,\n barMaxHeight,\n barOrigin,\n barWidth,\n track,\n ]);\n\n return (\n <canvas\n ref={canvasRef}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n }}\n />\n );\n }\n);\n\nVoiceVisualizer.displayName = \"VoiceVisualizer\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect, useId, useMemo } from \"react\";\n\nimport {\n registerMessageCallback,\n unregisterMessageCallback,\n} from \"./conversation/conversationActions\";\nimport {\n botOutputMessageStateAtom,\n messagesAtom,\n} from \"./conversation/conversationAtoms\";\nimport { useConversationContext } from \"./conversation/PipecatConversationProvider\";\nimport type {\n AggregationMetadata,\n ConversationMessage,\n ConversationMessagePart,\n} from \"./conversation/types\";\n\n/**\n * Options for `usePipecatConversation`.\n */\ninterface Props {\n /**\n * Called once when a brand-new message first enters the conversation.\n * The message may or may not be complete at this point — check `message.final`.\n */\n onMessageCreated?: (message: ConversationMessage) => void;\n /**\n * Called whenever an existing message's content changes\n * (e.g. streaming text appended, function call status changed, message finalized).\n * Check `message.final` to detect finalization.\n */\n onMessageUpdated?: (message: ConversationMessage) => void;\n /**\n * @deprecated Use `onMessageCreated` instead. Will be removed in a future release.\n */\n onMessageAdded?: (message: ConversationMessage) => void;\n /**\n * Metadata for aggregation types to control rendering and speech progress behavior.\n * Used to determine which aggregations should be excluded from position-based splitting.\n */\n aggregationMetadata?: Record<string, AggregationMetadata>;\n}\n\n/**\n * React hook for accessing and subscribing to the current conversation stream.\n *\n * This hook provides:\n * - The current list of conversation messages, ordered and merged for display.\n * - An `injectMessage` function to programmatically add a message to the conversation.\n * - Lifecycle callbacks: `onMessageCreated`, `onMessageUpdated`.\n *\n * Internally, this hook:\n * - Subscribes to conversation state updates and merges/filters messages for UI consumption.\n * - Ensures the provided callbacks are registered and unregistered as the component mounts/unmounts or the callbacks change.\n *\n * @param {Props} [options] - Optional configuration for the hook.\n * @returns {{\n * messages: ConversationMessage[];\n * injectMessage: (message: { role: \"user\" | \"assistant\" | \"system\"; parts: any[] }) => void;\n * }}\n */\nexport const usePipecatConversation = ({\n onMessageCreated,\n onMessageUpdated,\n onMessageAdded,\n aggregationMetadata,\n}: Props = {}) => {\n const { injectMessage } = useConversationContext();\n\n // Generate a unique ID for this hook instance\n const callbackId = useId();\n\n // Resolve deprecated onMessageAdded → onMessageCreated\n const resolvedCreated = onMessageCreated ?? onMessageAdded;\n\n // Register and unregister the callbacks\n const doRegister = useAtomCallback(\n useCallback(\n (get, set) => {\n registerMessageCallback(get, set, callbackId, {\n onMessageCreated: resolvedCreated,\n onMessageUpdated,\n });\n },\n [callbackId, resolvedCreated, onMessageUpdated]\n )\n );\n\n const doUnregister = useAtomCallback(\n useCallback(\n (get, set) => {\n unregisterMessageCallback(get, set, callbackId);\n },\n [callbackId]\n )\n );\n\n useEffect(() => {\n doRegister();\n return () => {\n doUnregister();\n };\n }, [doRegister, doUnregister]);\n\n // Get the raw state from atoms\n const messages = useAtomValue(messagesAtom);\n const botOutputMessageState = useAtomValue(botOutputMessageStateAtom);\n\n // Memoize the filtered messages to prevent infinite loops\n const filteredMessages = useMemo(() => {\n const getMetadata = (part: ConversationMessagePart) => {\n return part.aggregatedBy\n ? aggregationMetadata?.[part.aggregatedBy]\n : undefined;\n };\n\n // Process messages: convert string parts to BotOutputText based on position state\n const processedMessages = messages.map((message) => {\n if (message.role === \"assistant\") {\n const messageId = message.createdAt;\n const messageState = botOutputMessageState.get(messageId);\n\n if (!messageState) {\n // No state yet, return message as-is\n return message;\n }\n\n const parts = message.parts || [];\n\n // Find the actual current part index (skip parts that aren't meant to be spoken)\n let actualCurrentPartIndex = messageState.currentPartIndex;\n while (actualCurrentPartIndex < parts.length) {\n const part = parts[actualCurrentPartIndex];\n if (typeof part?.text !== \"string\") break;\n const isSpoken = getMetadata(part)?.isSpoken !== false;\n if (isSpoken) break;\n actualCurrentPartIndex++;\n }\n if (parts.length > 0 && actualCurrentPartIndex >= parts.length) {\n actualCurrentPartIndex = parts.length - 1;\n }\n\n // Convert parts to BotOutputText format based on position state\n const processedParts: ConversationMessagePart[] = parts.map(\n (part, partIndex) => {\n // If part text is not a string, it's already processed (e.g., ReactNode)\n if (typeof part.text !== \"string\") return part;\n\n const metadata = getMetadata(part);\n const displayMode =\n part.displayMode ?? metadata?.displayMode ?? \"inline\";\n const isSpoken = metadata?.isSpoken !== false;\n\n const partText =\n displayMode === \"block\" && !isSpoken\n ? part.text.trim()\n : part.text;\n if (!isSpoken) {\n return {\n ...part,\n displayMode,\n text: { spoken: \"\", unspoken: partText },\n };\n }\n\n // Use cursor split for the part at actualCurrentPartIndex for every message,\n // so previous (e.g. interrupted) messages keep partially spoken state.\n const isPartAtCursor = partIndex === actualCurrentPartIndex;\n const currentCharIndex = messageState.currentCharIndex;\n const spokenText = isPartAtCursor\n ? partText.slice(0, currentCharIndex)\n : partIndex < actualCurrentPartIndex\n ? partText\n : \"\";\n const unspokenText = isPartAtCursor\n ? partText.slice(currentCharIndex)\n : partIndex < actualCurrentPartIndex\n ? \"\"\n : partText;\n\n return {\n ...part,\n displayMode,\n text: { spoken: spokenText, unspoken: unspokenText },\n };\n }\n );\n\n return {\n ...message,\n parts: processedParts,\n };\n }\n return message;\n });\n\n // Messages are already normalized (sorted, filtered, deduped, merged) on write.\n return processedMessages;\n }, [messages, botOutputMessageState, aggregationMetadata]);\n\n return {\n messages: filteredMessages,\n injectMessage,\n };\n};\n"],"names":[],"version":3,"file":"index.module.js.map"}
1
+ {"mappings":"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","sources":["client-react/src/index.ts","client-react/src/PipecatClientAudio.tsx","client-react/src/usePipecatClientMediaTrack.ts","client-react/src/usePipecatClient.ts","client-react/src/PipecatClientProvider.tsx","client-react/package.json","client-react/src/conversation/PipecatConversationProvider.tsx","client-react/src/conversation/conversationActions.ts","client-react/src/conversation/botOutput.ts","client-react/src/conversation/conversationAtoms.ts","client-react/src/conversation/utils.ts","client-react/src/conversation/useConversationEventWiring.ts","client-react/src/useRTVIClientEvent.ts","client-react/src/RTVIEventContext.ts","client-react/src/PipecatClientState.tsx","client-react/src/PipecatClientCamToggle.tsx","client-react/src/usePipecatClientCamControl.ts","client-react/src/PipecatClientMicToggle.tsx","client-react/src/usePipecatClientMicControl.ts","client-react/src/PipecatClientScreenShareToggle.tsx","client-react/src/usePipecatClientScreenShareControl.ts","client-react/src/PipecatClientVideo.tsx","client-react/src/useMergedRef.ts","client-react/src/usePipecatClientMediaDevices.ts","client-react/src/usePipecatClientTransportState.ts","client-react/src/VoiceVisualizer.tsx","client-react/src/usePipecatConversation.ts"],"sourcesContent":["/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { PipecatClientAudio } from \"./PipecatClientAudio\";\nimport { PipecatClientCamToggle } from \"./PipecatClientCamToggle\";\nimport { PipecatClientMicToggle } from \"./PipecatClientMicToggle\";\nimport { PipecatClientProvider } from \"./PipecatClientProvider\";\nimport { PipecatClientScreenShareToggle } from \"./PipecatClientScreenShareToggle\";\nimport { PipecatClientVideo } from \"./PipecatClientVideo\";\nimport { usePipecatClient } from \"./usePipecatClient\";\nimport { usePipecatClientCamControl } from \"./usePipecatClientCamControl\";\nimport { usePipecatClientMediaDevices } from \"./usePipecatClientMediaDevices\";\nimport { usePipecatClientMediaTrack } from \"./usePipecatClientMediaTrack\";\nimport { usePipecatClientMicControl } from \"./usePipecatClientMicControl\";\nimport { usePipecatClientScreenShareControl } from \"./usePipecatClientScreenShareControl\";\nimport { usePipecatClientTransportState } from \"./usePipecatClientTransportState\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\nimport {\n deduplicateFunctionCalls,\n filterEmptyMessages,\n isMessageEmpty,\n mergeMessages,\n sortByCreatedAt,\n} from \"./conversation/conversationActions\";\nimport { useConversationContext } from \"./conversation/PipecatConversationProvider\";\nimport { usePipecatConversation } from \"./usePipecatConversation\";\n\nexport {\n PipecatClientAudio,\n PipecatClientCamToggle,\n PipecatClientMicToggle,\n PipecatClientProvider,\n PipecatClientScreenShareToggle,\n PipecatClientVideo,\n usePipecatClient,\n usePipecatClientCamControl,\n usePipecatClientMediaDevices,\n usePipecatClientMediaTrack,\n usePipecatClientMicControl,\n usePipecatClientScreenShareControl,\n usePipecatClientTransportState,\n useRTVIClientEvent,\n VoiceVisualizer,\n // Conversation\n useConversationContext,\n usePipecatConversation,\n deduplicateFunctionCalls,\n filterEmptyMessages,\n isMessageEmpty,\n mergeMessages,\n sortByCreatedAt,\n};\n\n// Conversation types\nexport type {\n AggregationMetadata,\n BotOutputText,\n ConversationMessage,\n ConversationMessagePart,\n FunctionCallData,\n FunctionCallRenderer,\n} from \"./conversation/types\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport { usePipecatClientMediaTrack } from \"./usePipecatClientMediaTrack\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\nexport const PipecatClientAudio = () => {\n const botAudioRef = useRef<HTMLAudioElement>(null);\n const botAudioTrack = usePipecatClientMediaTrack(\"audio\", \"bot\");\n\n useEffect(() => {\n if (!botAudioRef.current || !botAudioTrack) return;\n if (botAudioRef.current.srcObject) {\n const oldTrack = (\n botAudioRef.current.srcObject as MediaStream\n ).getAudioTracks()[0];\n if (oldTrack.id === botAudioTrack.id) return;\n }\n botAudioRef.current.srcObject = new MediaStream([botAudioTrack]);\n }, [botAudioTrack]);\n\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useCallback((speaker: MediaDeviceInfo) => {\n if (!botAudioRef.current) return;\n if (typeof botAudioRef.current.setSinkId !== \"function\") return;\n botAudioRef.current.setSinkId(speaker.deviceId);\n }, [])\n );\n\n return (\n <>\n <audio ref={botAudioRef} autoPlay />\n </>\n );\n};\nPipecatClientAudio.displayName = \"PipecatClientAudio\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { Participant, RTVIEvent, Tracks } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { atomFamily, useAtomCallback } from \"jotai/utils\";\nimport { PrimitiveAtom } from \"jotai/vanilla\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { usePipecatClient } from \"./usePipecatClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype ParticipantType = keyof Tracks;\ntype TrackType = keyof Tracks[\"local\"];\n\nconst localAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botVideoTrackAtom = atom<MediaStreamTrack | null>(null);\n\nconst trackAtom = atomFamily<\n { local: boolean; trackType: TrackType },\n PrimitiveAtom<MediaStreamTrack | null>\n>(({ local, trackType }) => {\n if (local) {\n switch (trackType) {\n case \"audio\":\n return localAudioTrackAtom;\n case \"screenAudio\":\n return localScreenAudioTrackAtom;\n case \"screenVideo\":\n return localScreenVideoTrackAtom;\n case \"video\":\n return localVideoTrackAtom;\n }\n }\n return trackType === \"audio\" ? botAudioTrackAtom : botVideoTrackAtom;\n});\n\nexport const usePipecatClientMediaTrack = (\n trackType: TrackType,\n participantType: ParticipantType\n) => {\n const client = usePipecatClient();\n const track = useAtomValue(\n trackAtom({ local: participantType === \"local\", trackType })\n );\n\n const updateTrack = useAtomCallback(\n useCallback(\n (\n get,\n set,\n track: MediaStreamTrack,\n trackType: TrackType,\n local: boolean\n ) => {\n const atom = trackAtom({\n local,\n trackType,\n });\n const oldTrack = get(atom);\n if (oldTrack?.id === track.id) return;\n set(atom, track);\n },\n []\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.TrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n updateTrack(\n track,\n track.kind as TrackType,\n Boolean(participant?.local)\n );\n },\n [updateTrack]\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.ScreenTrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n const trackType =\n track.kind === \"audio\" ? \"screenAudio\" : \"screenVideo\";\n updateTrack(track, trackType, Boolean(participant?.local));\n },\n [updateTrack]\n )\n );\n\n useEffect(() => {\n if (!client) return;\n const tracks = client.tracks();\n const track = tracks?.[participantType]?.[trackType];\n if (!track) return;\n updateTrack(track, trackType, participantType === \"local\");\n }, [participantType, trackType, updateTrack, client]);\n\n return track;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { PipecatClientContext } from \"./PipecatClientProvider\";\n\nexport const usePipecatClient = () => {\n const { client } = useContext(PipecatClientContext);\n return client;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport {\n PipecatClient,\n RTVIEvent,\n RTVIEventHandler,\n setAboutClient,\n} from \"@pipecat-ai/client-js\";\nimport { createStore } from \"jotai\";\nimport { Provider as JotaiProvider } from \"jotai/react\";\nimport React, { createContext, useCallback, useEffect, useRef } from \"react\";\n\nimport {\n name as packageName,\n version as packageVersion,\n} from \"../package.json\";\nimport { PipecatConversationProvider } from \"./conversation/PipecatConversationProvider\";\nimport { PipecatClientStateProvider } from \"./PipecatClientState\";\nimport { RTVIEventContext } from \"./RTVIEventContext\";\n\nexport interface Props {\n client: PipecatClient;\n jotaiStore?: React.ComponentProps<typeof JotaiProvider>[\"store\"];\n}\n\nconst defaultStore = createStore();\n\nexport const PipecatClientContext = createContext<{ client?: PipecatClient }>(\n {}\n);\n\ntype EventHandlersMap = {\n [E in RTVIEvent]?: Set<RTVIEventHandler<E>>;\n};\n\nexport const PipecatClientProvider: React.FC<\n React.PropsWithChildren<Props>\n> = ({ children, client, jotaiStore = defaultStore }) => {\n useEffect(() => {\n setAboutClient({\n library: packageName,\n library_version: packageVersion,\n });\n }, []);\n\n const eventHandlersMap = useRef<EventHandlersMap>({});\n\n useEffect(() => {\n if (!client) return;\n\n const allEvents = Object.values(RTVIEvent).filter((value) =>\n isNaN(Number(value))\n ) as RTVIEvent[];\n\n const allHandlers: Partial<\n Record<\n RTVIEvent,\n (\n ...args: Parameters<Exclude<RTVIEventHandler<RTVIEvent>, undefined>>\n ) => void\n >\n > = {};\n\n allEvents.forEach((event) => {\n type E = typeof event;\n type Handler = Exclude<RTVIEventHandler<E>, undefined>; // Remove undefined\n type Payload = Parameters<Handler>; // Will always be a tuple\n\n const handler = (...payload: Payload) => {\n const handlers = eventHandlersMap.current[event] as\n | Set<Handler>\n | undefined;\n if (!handlers) return;\n handlers.forEach((h) => {\n (\n h as (\n ...args: Parameters<Exclude<RTVIEventHandler<E>, undefined>>\n ) => void\n )(...payload);\n });\n };\n\n allHandlers[event] = handler;\n\n client.on(event, handler);\n });\n\n return () => {\n allEvents.forEach((event) => {\n client.off(event, allHandlers[event]);\n });\n };\n }, [client]);\n\n const on = useCallback(\n <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => {\n if (!eventHandlersMap.current[event]) {\n eventHandlersMap.current[event] = new Set();\n }\n eventHandlersMap.current[event]!.add(handler);\n },\n []\n );\n\n const off = useCallback(\n <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => {\n eventHandlersMap.current[event]?.delete(handler);\n },\n []\n );\n\n return (\n <JotaiProvider store={jotaiStore}>\n <PipecatClientContext.Provider value={{ client }}>\n <RTVIEventContext.Provider value={{ on, off }}>\n <PipecatClientStateProvider>\n <PipecatConversationProvider>\n {children}\n </PipecatConversationProvider>\n </PipecatClientStateProvider>\n </RTVIEventContext.Provider>\n </PipecatClientContext.Provider>\n </JotaiProvider>\n );\n};\nPipecatClientProvider.displayName = \"PipecatClientProvider\";\n","{\n \"name\": \"@pipecat-ai/client-react\",\n \"version\": \"1.2.1\",\n \"license\": \"BSD-2-Clause\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.module.js\",\n \"types\": \"dist/index.d.ts\",\n \"source\": \"src/index.ts\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/pipecat-ai/pipecat-client-web.git\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.module.js\",\n \"require\": \"./dist/index.js\"\n }\n },\n \"files\": [\n \"dist\",\n \"package.json\",\n \"README.md\"\n ],\n \"scripts\": {\n \"build\": \"parcel build --no-cache\",\n \"dev\": \"parcel watch\",\n \"lint\": \"eslint . --report-unused-disable-directives --max-warnings 0 --ignore-pattern 'dist/'\",\n \"test\": \"jest\"\n },\n \"jest\": {\n \"preset\": \"ts-jest\",\n \"testEnvironment\": \"jsdom\",\n \"moduleNameMapper\": {\n \"^@/(.*)$\": \"<rootDir>/src/$1\"\n },\n \"transform\": {\n \"^.+\\\\.tsx?$\": [\n \"ts-jest\",\n {\n \"tsconfig\": {\n \"jsx\": \"react-jsx\",\n \"module\": \"commonjs\",\n \"moduleResolution\": \"node\",\n \"esModuleInterop\": true,\n \"allowImportingTsExtensions\": false,\n \"noUnusedLocals\": false,\n \"noUnusedParameters\": false\n }\n }\n ]\n }\n },\n \"devDependencies\": {\n \"@jest/globals\": \"^30.2.0\",\n \"@pipecat-ai/client-js\": \"*\",\n \"@types/jest\": \"^30.0.0\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@typescript-eslint/eslint-plugin\": \"^8.32.0\",\n \"eslint\": \"^9.11.1\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"eslint-plugin-react-hooks\": \"^5.2.0\",\n \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n \"jest\": \"^30.2.0\",\n \"jest-environment-jsdom\": \"^30.2.0\",\n \"parcel\": \"^2.12.0\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"ts-jest\": \"^29.4.6\",\n \"typescript\": \"^5.2.2\"\n },\n \"peerDependencies\": {\n \"@pipecat-ai/client-js\": \"*\",\n \"react\": \">=18\",\n \"react-dom\": \">=18\"\n },\n \"dependencies\": {\n \"jotai\": \"^2.9.0\"\n }\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport React, { createContext, useCallback, useContext } from \"react\";\n\nimport { injectMessage as injectMessageAction } from \"./conversationActions\";\nimport { botOutputSupportedAtom } from \"./conversationAtoms\";\nimport type { ConversationMessagePart } from \"./types\";\nimport { useConversationEventWiring } from \"./useConversationEventWiring\";\n\ninterface ConversationContextValue {\n injectMessage: (message: {\n role: \"user\" | \"assistant\" | \"system\";\n parts: ConversationMessagePart[];\n }) => void;\n /**\n * Whether BotOutput events are supported (RTVI 1.1.0+)\n * null = unknown (before BotReady), true = supported, false = not supported\n */\n botOutputSupported: boolean | null;\n}\n\nexport const ConversationContext =\n createContext<ConversationContextValue | null>(null);\n\nexport const PipecatConversationProvider: React.FC<React.PropsWithChildren> = ({\n children,\n}) => {\n useConversationEventWiring();\n\n const injectMessage = useAtomCallback(\n useCallback((get, set, message: {\n role: \"user\" | \"assistant\" | \"system\";\n parts: ConversationMessagePart[];\n }) => {\n injectMessageAction(get, set, message);\n }, [])\n );\n\n const botOutputSupported = useAtomValue(botOutputSupportedAtom);\n\n return (\n <ConversationContext.Provider value={{ injectMessage, botOutputSupported }}>\n {children}\n </ConversationContext.Provider>\n );\n};\nPipecatConversationProvider.displayName = \"PipecatConversationProvider\";\n\nexport const useConversationContext = (): ConversationContextValue => {\n const context = useContext(ConversationContext);\n if (!context) {\n throw new Error(\n \"useConversationContext must be used within a PipecatClientProvider\"\n );\n }\n return context;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport type { Getter, Setter } from \"jotai\";\nimport type { ReactNode } from \"react\";\n\nimport { applySpokenBotOutputProgress } from \"./botOutput\";\nimport type { MessageCallbacks } from \"./conversationAtoms\";\nimport {\n botOutputMessageStateAtom,\n messageCallbacksAtom,\n messagesAtom,\n} from \"./conversationAtoms\";\nimport type {\n BotOutputText,\n ConversationMessage,\n ConversationMessagePart,\n FunctionCallData,\n} from \"./types\";\nimport { findLast, findLastIndex } from \"./utils\";\n\n/** Max time gap (ms) between consecutive same-role messages for merging. */\nconst MERGE_WINDOW_MS = 30_000;\n\n/**\n * Unicode characters used by `FilterIncompleteTurns` on the server to mark\n * turn completion status. The LLM emits one of these as the very first\n * character of every response:\n *\n * ✓ (U+2713) — complete turn\n * ○ (U+25CB) — incomplete short\n * ◐ (U+25D0) — incomplete long\n *\n * They must be stripped before the text reaches conversation state.\n */\nconst TURN_COMPLETION_MARKERS = new Set([\"\\u2713\", \"\\u25CB\", \"\\u25D0\"]);\n\n/**\n * Strip a leading turn-completion marker (and any trailing space) from `text`.\n * Returns the cleaned string, which may be empty.\n */\nexport function stripTurnCompletionMarker(text: string): string {\n if (text.length === 0) return text;\n if (TURN_COMPLETION_MARKERS.has(text[0])) {\n // Remove marker and optional single trailing space\n return text[1] === \" \" ? text.slice(2) : text.slice(1);\n }\n return text;\n}\n\n// ---------------------------------------------------------------------------\n// Public utility functions (exported for consumers)\n// ---------------------------------------------------------------------------\n\nexport const sortByCreatedAt = (\n a: ConversationMessage,\n b: ConversationMessage\n): number => {\n return a.createdAt < b.createdAt ? -1 : a.createdAt > b.createdAt ? 1 : 0;\n};\n\nexport const isMessageEmpty = (message: ConversationMessage): boolean => {\n if (message.role === \"function_call\") return false;\n const parts = message.parts || [];\n if (parts.length === 0) return true;\n return parts.every((p) => {\n if (typeof p.text === \"string\") {\n return p.text.trim().length === 0;\n }\n // Check BotOutputText objects\n if (\n typeof p.text === \"object\" &&\n p.text !== null &&\n \"spoken\" in p.text &&\n \"unspoken\" in p.text\n ) {\n const botText = p.text as BotOutputText;\n return (\n botText.spoken.trim().length === 0 &&\n botText.unspoken.trim().length === 0\n );\n }\n // For ReactNode, consider it non-empty\n return false;\n });\n};\n\nexport const filterEmptyMessages = (\n messages: ConversationMessage[]\n): ConversationMessage[] => {\n return messages.filter((message, index, array) => {\n if (!isMessageEmpty(message)) return true;\n\n // For empty messages, keep only if no following non-empty message with same role\n const nextMessageWithSameRole = array\n .slice(index + 1)\n .find((m) => m.role === message.role && !isMessageEmpty(m));\n\n return !nextMessageWithSameRole;\n });\n};\n\nexport const mergeMessages = (\n messages: ConversationMessage[]\n): ConversationMessage[] => {\n const mergedMessages: ConversationMessage[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const currentMessage = messages[i];\n const lastMerged = mergedMessages[mergedMessages.length - 1];\n\n const timeDiff = lastMerged\n ? Math.abs(\n new Date(currentMessage.createdAt).getTime() -\n new Date(lastMerged.createdAt).getTime()\n )\n : Infinity;\n\n const shouldMerge =\n lastMerged &&\n lastMerged.role === currentMessage.role &&\n currentMessage.role !== \"system\" &&\n currentMessage.role !== \"function_call\" &&\n timeDiff < MERGE_WINDOW_MS;\n\n if (shouldMerge) {\n mergedMessages[mergedMessages.length - 1] = {\n ...lastMerged,\n parts: [...(lastMerged.parts || []), ...(currentMessage.parts || [])],\n updatedAt: currentMessage.updatedAt || currentMessage.createdAt,\n final: currentMessage.final !== false,\n };\n } else {\n mergedMessages.push(currentMessage);\n }\n }\n\n return mergedMessages;\n};\n\nconst statusPriority: Record<string, number> = {\n started: 0,\n in_progress: 1,\n completed: 2,\n};\n\n/**\n * Deduplicate function call messages that share the same tool_call_id,\n * keeping the entry with the most advanced status.\n */\nexport const deduplicateFunctionCalls = (\n messages: ConversationMessage[]\n): ConversationMessage[] => {\n const bestByToolCallId = new Map<string, number>();\n const toRemove = new Set<number>();\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n const tcid = msg.functionCall?.tool_call_id;\n if (msg.role !== \"function_call\" || !tcid) continue;\n\n const existingIdx = bestByToolCallId.get(tcid);\n if (existingIdx !== undefined) {\n const existingPriority =\n statusPriority[messages[existingIdx].functionCall!.status] ?? 0;\n const currentPriority = statusPriority[msg.functionCall!.status] ?? 0;\n\n if (currentPriority >= existingPriority) {\n toRemove.add(existingIdx);\n bestByToolCallId.set(tcid, i);\n } else {\n toRemove.add(i);\n }\n } else {\n bestByToolCallId.set(tcid, i);\n }\n }\n\n if (toRemove.size === 0) return messages;\n return messages.filter((_, i) => !toRemove.has(i));\n};\n\nconst normalizeMessagesForUI = (\n messages: ConversationMessage[]\n): ConversationMessage[] => {\n return mergeMessages(\n deduplicateFunctionCalls(\n filterEmptyMessages([...messages].sort(sortByCreatedAt))\n )\n );\n};\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst callCallbacks = (\n callbacksMap: Map<string, MessageCallbacks>,\n type: keyof MessageCallbacks,\n message: ConversationMessage\n) => {\n callbacksMap.forEach((callbacks) => {\n try {\n callbacks[type]?.(message);\n } catch (error) {\n console.error(`Error in ${type} callback:`, error);\n }\n });\n};\n\n// ---------------------------------------------------------------------------\n// Action functions – (get, set, …params) => void\n// ---------------------------------------------------------------------------\n\nexport function registerMessageCallback(\n get: Getter,\n set: Setter,\n id: string,\n callbacks: MessageCallbacks\n) {\n const map = new Map(get(messageCallbacksAtom));\n map.set(id, callbacks);\n set(messageCallbacksAtom, map);\n}\n\nexport function unregisterMessageCallback(\n get: Getter,\n set: Setter,\n id: string\n) {\n const map = new Map(get(messageCallbacksAtom));\n map.delete(id);\n set(messageCallbacksAtom, map);\n}\n\nexport function clearMessages(_get: Getter, set: Setter) {\n set(messagesAtom, []);\n set(botOutputMessageStateAtom, new Map());\n}\n\nexport function addMessage(\n get: Getter,\n set: Setter,\n messageData: Omit<ConversationMessage, \"createdAt\" | \"updatedAt\">\n) {\n const now = new Date();\n const message: ConversationMessage = {\n ...messageData,\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n };\n\n const current = get(messagesAtom);\n const updatedMessages = [...current, message];\n const processedMessages = normalizeMessagesForUI(updatedMessages);\n\n callCallbacks(get(messageCallbacksAtom), \"onMessageCreated\", message);\n set(messagesAtom, processedMessages);\n}\n\nexport function updateLastMessage(\n get: Getter,\n set: Setter,\n role: \"user\" | \"assistant\",\n updates: Partial<ConversationMessage>\n) {\n const messages = [...get(messagesAtom)];\n const lastMessageIndex = findLastIndex(messages,(msg) => msg.role === role);\n\n if (lastMessageIndex === -1) return;\n\n const existing = messages[lastMessageIndex];\n const updatedMessage = {\n ...existing,\n ...updates,\n updatedAt: new Date().toISOString(),\n } as ConversationMessage;\n\n messages[lastMessageIndex] = updatedMessage;\n const processedMessages = normalizeMessagesForUI(messages);\n\n callCallbacks(get(messageCallbacksAtom), \"onMessageUpdated\", updatedMessage);\n set(messagesAtom, processedMessages);\n}\n\nexport function finalizeLastMessage(\n get: Getter,\n set: Setter,\n role: \"user\" | \"assistant\"\n) {\n const messages = [...get(messagesAtom)];\n const lastMessageIndex = findLastIndex(messages,(msg) => msg.role === role);\n\n if (lastMessageIndex === -1) return;\n\n const lastMessage = messages[lastMessageIndex];\n\n // Check if message is empty\n if (isMessageEmpty(lastMessage)) {\n // Remove empty message only if it has no text in streams either\n messages.splice(lastMessageIndex, 1);\n } else {\n // Finalize message and its last part\n const parts = [...(lastMessage.parts || [])];\n if (parts.length > 0) {\n parts[parts.length - 1] = {\n ...parts[parts.length - 1],\n final: true,\n };\n }\n messages[lastMessageIndex] = {\n ...lastMessage,\n parts,\n final: true,\n updatedAt: new Date().toISOString(),\n };\n callCallbacks(\n get(messageCallbacksAtom),\n \"onMessageUpdated\",\n messages[lastMessageIndex]\n );\n }\n\n const processedMessages = normalizeMessagesForUI(messages);\n set(messagesAtom, processedMessages);\n}\n\nexport function removeEmptyLastMessage(\n get: Getter,\n set: Setter,\n role: \"user\" | \"assistant\"\n) {\n const messages = [...get(messagesAtom)];\n const lastMessageIndex = findLastIndex(messages,(msg) => msg.role === role);\n\n if (lastMessageIndex === -1) return;\n\n const lastMessage = messages[lastMessageIndex];\n\n if (isMessageEmpty(lastMessage)) {\n messages.splice(lastMessageIndex, 1);\n const processedMessages = normalizeMessagesForUI(messages);\n set(messagesAtom, processedMessages);\n }\n}\n\nexport function injectMessage(\n get: Getter,\n set: Setter,\n messageData: {\n role: \"user\" | \"assistant\" | \"system\";\n parts: ConversationMessagePart[];\n }\n) {\n const now = new Date();\n const current = get(messagesAtom);\n\n // If the most recent message is an active (non-final) assistant message,\n // backdate the injected message so it sorts before the assistant's createdAt.\n // This prevents the injected message from splitting the bot's response across\n // two bubbles and breaking the karaoke cursor.\n const lastMessage = current[current.length - 1];\n const lastAssistant =\n lastMessage?.role === \"assistant\" ? lastMessage : undefined;\n let timestamp: string;\n if (\n lastAssistant &&\n lastAssistant.final === false &&\n messageData.role === \"system\"\n ) {\n const assistantTime = new Date(lastAssistant.createdAt);\n timestamp = new Date(assistantTime.getTime() - 1).toISOString();\n } else {\n timestamp = now.toISOString();\n }\n\n const message: ConversationMessage = {\n role: messageData.role,\n final: true,\n parts: [...messageData.parts],\n createdAt: timestamp,\n updatedAt: now.toISOString(),\n };\n\n const updatedMessages = [...current, message];\n const processedMessages = normalizeMessagesForUI(updatedMessages);\n\n callCallbacks(get(messageCallbacksAtom), \"onMessageCreated\", message);\n set(messagesAtom, processedMessages);\n}\n\nexport function upsertUserTranscript(\n get: Getter,\n set: Setter,\n text: string | ReactNode,\n final: boolean\n) {\n const now = new Date();\n const messages = [...get(messagesAtom)];\n\n // Find last user message\n const lastUserIndex = findLastIndex(messages,(m) => m.role === \"user\");\n\n if (lastUserIndex !== -1 && !messages[lastUserIndex].final) {\n // Update existing user message\n const target = { ...messages[lastUserIndex] };\n const parts: ConversationMessagePart[] = Array.isArray(target.parts)\n ? [...target.parts]\n : [];\n\n const lastPart = parts[parts.length - 1];\n if (!lastPart || lastPart.final) {\n // Start a new part\n parts.push({ text, final, createdAt: now.toISOString() });\n } else {\n // Update in-progress part\n parts[parts.length - 1] = {\n ...lastPart,\n text,\n final,\n };\n }\n\n const updatedMessage: ConversationMessage = {\n ...target,\n parts,\n updatedAt: now.toISOString(),\n };\n\n messages[lastUserIndex] = updatedMessage;\n\n const processedMessages = normalizeMessagesForUI(messages);\n\n callCallbacks(get(messageCallbacksAtom), \"onMessageUpdated\", updatedMessage);\n set(messagesAtom, processedMessages);\n return;\n }\n\n // Create a new user message initialized with this transcript\n const newMessage: ConversationMessage = {\n role: \"user\",\n final: false,\n parts: [\n {\n text,\n final,\n createdAt: now.toISOString(),\n },\n ],\n createdAt: now.toISOString(),\n updatedAt: now.toISOString(),\n };\n\n const updatedMessages = [...messages, newMessage];\n const processedMessages = normalizeMessagesForUI(updatedMessages);\n callCallbacks(get(messageCallbacksAtom), \"onMessageCreated\", newMessage);\n set(messagesAtom, processedMessages);\n}\n\nexport function updateAssistantBotOutput(\n get: Getter,\n set: Setter,\n text: string,\n final: boolean,\n spoken: boolean,\n aggregatedBy?: string\n) {\n // Strip turn-completion markers emitted by FilterIncompleteTurns before\n // the text enters conversation state.\n text = stripTurnCompletionMarker(text);\n if (text.length === 0) return;\n\n const now = new Date();\n const messages = [...get(messagesAtom)];\n const botOutputMessageState = new Map(get(botOutputMessageStateAtom));\n\n const lastAssistantIndex = findLastIndex(messages,\n (msg) => msg.role === \"assistant\"\n );\n\n let messageId: string;\n let isNewMessage = false;\n\n if (lastAssistantIndex === -1) {\n // Create new assistant message\n isNewMessage = true;\n messageId = now.toISOString();\n const newMessage: ConversationMessage = {\n role: \"assistant\",\n final,\n parts: [],\n createdAt: messageId,\n updatedAt: messageId,\n };\n messages.push(newMessage);\n // Initialize message state\n botOutputMessageState.set(messageId, {\n currentPartIndex: 0,\n currentCharIndex: 0,\n partFinalFlags: [],\n });\n } else {\n // Update existing assistant message\n const lastMessage = messages[lastAssistantIndex];\n messageId = lastMessage.createdAt;\n\n messages[lastAssistantIndex] = {\n ...lastMessage,\n final: final ? true : lastMessage.final,\n updatedAt: now.toISOString(),\n };\n\n // Ensure message state exists\n if (!botOutputMessageState.has(messageId)) {\n botOutputMessageState.set(messageId, {\n currentPartIndex: 0,\n currentCharIndex: 0,\n partFinalFlags: [],\n });\n }\n }\n\n const messageState = botOutputMessageState.get(messageId)!;\n const message =\n messages[\n lastAssistantIndex === -1 ? messages.length - 1 : lastAssistantIndex\n ];\n const parts = [...(message.parts || [])];\n\n if (!spoken) {\n // UNSPOKEN EVENT: Create/update message parts immediately\n // Only append when both current and last part are word-level; sentence-level\n // and other types each get their own part so spoken events can match 1:1.\n const isDefaultType =\n aggregatedBy === \"sentence\" ||\n aggregatedBy === \"word\" ||\n !aggregatedBy;\n const lastPart = parts[parts.length - 1];\n const shouldAppend =\n lastPart &&\n aggregatedBy === \"word\" &&\n lastPart.aggregatedBy === \"word\" &&\n typeof lastPart.text === \"string\";\n\n if (shouldAppend) {\n // Append to last part (word-level only)\n const lastPartText = lastPart.text as string;\n const separator =\n lastPartText && !lastPartText.endsWith(\" \") && !text.startsWith(\" \")\n ? \" \"\n : \"\";\n parts[parts.length - 1] = {\n ...lastPart,\n text: lastPartText + separator + text,\n };\n } else {\n // Create new part (sentence-level, custom types, or first word chunk)\n // Default to inline; custom types get displayMode from metadata in the hook\n const defaultDisplayMode = isDefaultType ? \"inline\" : undefined;\n const newPart: ConversationMessagePart = {\n text: text, // Store full text as string\n final: false, // Will be evaluated in hook based on metadata\n createdAt: now.toISOString(),\n aggregatedBy,\n displayMode: defaultDisplayMode,\n };\n parts.push(newPart);\n // Extend partFinalFlags array\n messageState.partFinalFlags.push(false);\n }\n\n // Update message with new parts\n messages[\n lastAssistantIndex === -1 ? messages.length - 1 : lastAssistantIndex\n ] = {\n ...message,\n parts,\n };\n } else {\n // SPOKEN EVENT: advance cursor into existing text, or add as new part if\n // there is none (bots that only send spoken: true, never unspoken).\n const advanced =\n parts.length > 0 &&\n applySpokenBotOutputProgress(messageState, parts, text);\n\n if (!advanced) {\n // No unspoken content to advance: add this text as a part already fully spoken\n const isDefaultType =\n aggregatedBy === \"sentence\" ||\n aggregatedBy === \"word\" ||\n !aggregatedBy;\n const defaultDisplayMode = isDefaultType ? \"inline\" : undefined;\n const newPart: ConversationMessagePart = {\n text,\n final: false,\n createdAt: now.toISOString(),\n aggregatedBy,\n displayMode: defaultDisplayMode,\n };\n parts.push(newPart);\n messageState.partFinalFlags.push(true);\n messageState.currentPartIndex = parts.length - 1;\n messageState.currentCharIndex = text.length;\n\n messages[\n lastAssistantIndex === -1 ? messages.length - 1 : lastAssistantIndex\n ] = {\n ...message,\n parts,\n };\n }\n }\n\n const processedMessages = normalizeMessagesForUI(messages);\n\n const cbs = get(messageCallbacksAtom);\n const updatedMsg =\n messages[\n lastAssistantIndex === -1 ? messages.length - 1 : lastAssistantIndex\n ];\n if (isNewMessage) {\n callCallbacks(cbs, \"onMessageCreated\", updatedMsg);\n } else {\n callCallbacks(cbs, \"onMessageUpdated\", updatedMsg);\n }\n\n set(messagesAtom, processedMessages);\n set(botOutputMessageStateAtom, botOutputMessageState);\n}\n\nexport function addFunctionCall(\n get: Getter,\n set: Setter,\n data: {\n function_name?: string;\n tool_call_id?: string;\n args?: Record<string, unknown>;\n }\n) {\n const messages = get(messagesAtom);\n\n // If a tool_call_id is provided, check for an existing entry to avoid duplicates\n if (data.tool_call_id) {\n const existingIndex = findLastIndex(messages,\n (msg) =>\n msg.role === \"function_call\" &&\n msg.functionCall?.tool_call_id === data.tool_call_id\n );\n if (existingIndex !== -1) return;\n }\n\n const now = new Date();\n\n // If the most recent message is an active (non-final) assistant message,\n // backdate the function call so it sorts before the assistant's createdAt.\n // This prevents the function call from splitting the bot's response across\n // two bubbles and breaking the karaoke cursor.\n const lastMessage = messages[messages.length - 1];\n let timestamp: string;\n if (\n lastMessage?.role === \"assistant\" &&\n lastMessage.final === false\n ) {\n const assistantTime = new Date(lastMessage.createdAt);\n timestamp = new Date(assistantTime.getTime() - 1).toISOString();\n } else {\n timestamp = now.toISOString();\n }\n\n const message: ConversationMessage = {\n role: \"function_call\",\n final: false,\n parts: [],\n createdAt: timestamp,\n updatedAt: now.toISOString(),\n functionCall: {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n args: data.args,\n status: \"started\",\n },\n };\n\n const updatedMessages = [...messages, message];\n const processedMessages = normalizeMessagesForUI(updatedMessages);\n callCallbacks(get(messageCallbacksAtom), \"onMessageCreated\", message);\n set(messagesAtom, processedMessages);\n}\n\nexport function updateFunctionCall(\n get: Getter,\n set: Setter,\n tool_call_id: string,\n updates: Partial<\n Pick<\n FunctionCallData,\n \"status\" | \"result\" | \"cancelled\" | \"args\" | \"function_name\" | \"tool_call_id\"\n >\n >\n): boolean {\n const messages = [...get(messagesAtom)];\n const index = findLastIndex(messages,\n (msg) =>\n msg.role === \"function_call\" &&\n msg.functionCall?.tool_call_id === tool_call_id\n );\n if (index === -1) return false;\n\n const existing = messages[index];\n const updated: ConversationMessage = {\n ...existing,\n updatedAt: new Date().toISOString(),\n final: updates.status === \"completed\" ? true : existing.final,\n functionCall: {\n ...existing.functionCall!,\n ...updates,\n },\n };\n messages[index] = updated;\n\n const processedMessages = normalizeMessagesForUI(messages);\n callCallbacks(get(messageCallbacksAtom), \"onMessageUpdated\", updated);\n set(messagesAtom, processedMessages);\n return true;\n}\n\n/**\n * Update the most recent function call message that has status \"started\"\n * and no tool_call_id yet. Used when transitioning from Started → InProgress.\n */\nexport function updateLastStartedFunctionCall(\n get: Getter,\n set: Setter,\n updates: Partial<\n Pick<FunctionCallData, \"status\" | \"tool_call_id\" | \"args\" | \"function_name\">\n >\n): boolean {\n const messages = [...get(messagesAtom)];\n const index = findLastIndex(messages,\n (msg) =>\n msg.role === \"function_call\" &&\n msg.functionCall?.status === \"started\" &&\n !msg.functionCall?.tool_call_id\n );\n if (index === -1) return false;\n\n const existing = messages[index];\n const updated: ConversationMessage = {\n ...existing,\n updatedAt: new Date().toISOString(),\n functionCall: {\n ...existing.functionCall!,\n ...updates,\n },\n };\n messages[index] = updated;\n\n const processedMessages = normalizeMessagesForUI(messages);\n callCallbacks(get(messageCallbacksAtom), \"onMessageUpdated\", updated);\n set(messagesAtom, processedMessages);\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// High-level function call lifecycle handlers\n// ---------------------------------------------------------------------------\n\nexport function handleFunctionCallStarted(\n get: Getter,\n set: Setter,\n data: { function_name?: string }\n) {\n const messages = get(messagesAtom);\n const lastFc = findLast(messages,\n (m: ConversationMessage) => m.role === \"function_call\"\n );\n\n // Check if InProgress already created an entry (events arrived out of order).\n if (\n lastFc?.functionCall &&\n lastFc.functionCall.status !== \"started\" &&\n Date.now() - new Date(lastFc.updatedAt ?? lastFc.createdAt).getTime() < 2000\n ) {\n if (\n data.function_name &&\n !lastFc.functionCall.function_name &&\n lastFc.functionCall.tool_call_id\n ) {\n updateFunctionCall(get, set, lastFc.functionCall.tool_call_id, {\n function_name: data.function_name,\n });\n }\n return;\n }\n\n addFunctionCall(get, set, { function_name: data.function_name });\n}\n\nexport function handleFunctionCallInProgress(\n get: Getter,\n set: Setter,\n data: {\n function_name?: string;\n tool_call_id: string;\n args?: Record<string, unknown>;\n }\n) {\n // Tier 1: Try to update the last \"started\" entry (from LLMFunctionCallStarted)\n const updated = updateLastStartedFunctionCall(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n args: data.args,\n status: \"in_progress\",\n });\n\n if (!updated) {\n // Tier 2: Try updating an existing entry by tool_call_id\n const found = updateFunctionCall(get, set, data.tool_call_id, {\n function_name: data.function_name,\n args: data.args,\n status: \"in_progress\",\n });\n\n if (!found) {\n // Tier 3: No existing entry at all; create a new one as in_progress\n addFunctionCall(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n args: data.args,\n });\n updateFunctionCall(get, set, data.tool_call_id, {\n status: \"in_progress\",\n });\n }\n }\n}\n\nexport function handleFunctionCallStopped(\n get: Getter,\n set: Setter,\n data: {\n function_name?: string;\n tool_call_id: string;\n result?: unknown;\n cancelled?: boolean;\n }\n) {\n // Tier 1: Try updating by tool_call_id\n const found = updateFunctionCall(get, set, data.tool_call_id, {\n function_name: data.function_name,\n status: \"completed\",\n result: data.result,\n cancelled: data.cancelled,\n });\n\n if (!found) {\n // Tier 2: No match by tool_call_id (e.g. InProgress was skipped).\n const matched = updateLastStartedFunctionCall(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n });\n if (matched) {\n updateFunctionCall(get, set, data.tool_call_id, {\n status: \"completed\",\n result: data.result,\n cancelled: data.cancelled,\n });\n }\n }\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport type { ConversationMessagePart } from \"./types\";\n\nexport type BotOutputMessageCursor = {\n currentPartIndex: number;\n currentCharIndex: number;\n /**\n * Per-part: true if fully spoken OR explicitly skipped (e.g. not meant\n * to be spoken, or mismatch recovery advanced past it).\n */\n partFinalFlags: boolean[];\n};\n\nexport const normalizeForMatching = (text: string): string => {\n return text.toLowerCase().replace(/[^\\p{L}\\p{N}\\s]/gu, \"\");\n};\n\nconst skipWhitespace = (text: string, start: number): number => {\n let i = start;\n while (i < text.length && /\\s/.test(text[i])) i++;\n return i;\n};\n\n/**\n * Finds where `spoken` appears in `unspoken`, starting from `startPosition`.\n * - Best-effort sequential word matching (normalized, punctuation-stripped)\n * - Returns the original start position on mismatch (no advancement)\n */\nconst findSpokenPositionInUnspoken = (\n spoken: string,\n unspoken: string,\n startPosition: number\n): number => {\n if (!spoken || !unspoken || startPosition >= unspoken.length) {\n return startPosition;\n }\n\n // If spoken text includes a leading separator space, skip leading whitespace in unspoken.\n let actualStart = startPosition;\n let spokenForMatching = spoken;\n if (spoken.startsWith(\" \") && startPosition < unspoken.length) {\n actualStart = skipWhitespace(unspoken, startPosition);\n spokenForMatching = spoken.trimStart();\n } else if (startPosition === 0 && startPosition < unspoken.length) {\n // If we're at the start, also skip leading whitespace (e.g. newlines)\n actualStart = skipWhitespace(unspoken, 0);\n }\n\n const remainder = unspoken.slice(actualStart);\n // Sentence-level: if spoken exactly matches the remainder (normalized), consume the whole part\n // so we never leave a word unspoken due to word-matching edge cases.\n if (\n normalizeForMatching(spokenForMatching).trim() ===\n normalizeForMatching(remainder).trim()\n ) {\n return unspoken.length;\n }\n\n const spokenWords = normalizeForMatching(spokenForMatching)\n .split(/\\s+/)\n .filter(Boolean);\n\n if (spokenWords.length === 0) return actualStart;\n\n const unspokenWords = normalizeForMatching(unspoken.slice(actualStart))\n .split(/\\s+/)\n .filter(Boolean);\n\n // Sequential match, allowing prefix match for contractions (e.g. \"I\" vs \"I'm\")\n // and limited skipping of mismatched unspoken words (e.g. punctuation artifacts).\n let matchedWords = 0;\n let consecutiveSkips = 0;\n const MAX_CONSECUTIVE_SKIPS = 2;\n for (\n let i = 0;\n i < unspokenWords.length && matchedWords < spokenWords.length;\n i++\n ) {\n const target = spokenWords[matchedWords];\n const candidate = unspokenWords[i];\n if (candidate === target || candidate.startsWith(target)) {\n matchedWords++;\n consecutiveSkips = 0;\n continue;\n }\n consecutiveSkips++;\n if (consecutiveSkips > MAX_CONSECUTIVE_SKIPS) return actualStart;\n // Skip this unspoken word and try matching the next one\n }\n\n if (matchedWords < spokenWords.length) return actualStart;\n\n // Convert word matches back into a character position in the original unspoken string.\n const isWordChar = (char: string): boolean => /[\\p{L}\\p{N}]/u.test(char);\n let wordCount = 0;\n let i = actualStart;\n let inWord = false;\n\n while (i < unspoken.length) {\n const charIsWord = isWordChar(unspoken[i]);\n if (charIsWord && !inWord) {\n inWord = true;\n wordCount++;\n\n if (wordCount === matchedWords) {\n // Consume the rest of this word\n i++;\n while (i < unspoken.length && isWordChar(unspoken[i])) i++;\n // Include any punctuation after the word until the next space, then include the space\n while (i < unspoken.length) {\n if (unspoken[i] === \" \") {\n i++;\n break;\n }\n i++;\n }\n return i;\n }\n } else if (!charIsWord && inWord) {\n inWord = false;\n }\n i++;\n }\n\n return unspoken.length;\n};\n\n/**\n * Returns true if the cursor has not yet reached the end of all text parts,\n * meaning there is still unspoken content waiting to be spoken.\n */\nexport function hasUnspokenContent(\n cursor: BotOutputMessageCursor,\n parts: ConversationMessagePart[]\n): boolean {\n if (parts.length === 0) return false;\n\n for (let i = 0; i < parts.length; i++) {\n if (typeof parts[i]?.text !== \"string\") continue;\n if (!cursor.partFinalFlags[i]) return true;\n }\n\n return false;\n}\n\n/**\n * Attempts to consume spoken text against the current cursor position.\n * Returns true if the text was successfully consumed (cursor may or may not\n * advance — pure punctuation is consumed without moving the cursor), or false\n * if there was nothing to consume (e.g. no parts, all parts already spoken).\n * Used to detect \"spoken-only\" bots that never send unspoken events.\n */\nexport function applySpokenBotOutputProgress(\n cursor: BotOutputMessageCursor,\n parts: ConversationMessagePart[],\n spokenText: string\n): boolean {\n if (parts.length === 0) return false;\n\n // Find the next part that should be spoken (skip parts already marked final/skipped)\n let partToMatch = cursor.currentPartIndex;\n while (partToMatch < parts.length && cursor.partFinalFlags[partToMatch]) {\n partToMatch++;\n }\n if (partToMatch >= parts.length) return false;\n\n if (partToMatch > cursor.currentPartIndex) {\n cursor.currentPartIndex = partToMatch;\n cursor.currentCharIndex = 0;\n }\n\n const currentPart = parts[cursor.currentPartIndex];\n if (typeof currentPart.text !== \"string\") return false;\n\n const partText = currentPart.text;\n const startChar = cursor.currentCharIndex;\n\n // If the spoken text is pure punctuation (e.g. an em dash \"—\"), normalization\n // strips it to empty and word-matching would fail. Treat it as successfully\n // consumed so the cursor stays put and subsequent words continue matching.\n if (normalizeForMatching(spokenText).trim().length === 0) {\n return true;\n }\n\n const newPosition = findSpokenPositionInUnspoken(\n spokenText,\n partText,\n startChar\n );\n const whitespaceEnd = skipWhitespace(partText, startChar);\n\n if (newPosition > whitespaceEnd) {\n cursor.currentCharIndex = newPosition;\n\n if (newPosition >= partText.length) {\n cursor.partFinalFlags[cursor.currentPartIndex] = true;\n if (cursor.currentPartIndex < parts.length - 1) {\n cursor.currentPartIndex++;\n cursor.currentCharIndex = 0;\n }\n }\n return true;\n }\n\n // Intra-part scan-ahead recovery: if matching failed at the current position,\n // scan forward word-by-word within the same part. This prevents the cursor\n // from getting permanently stuck mid-part when a single word mismatch occurs\n // (e.g. TTS variation, punctuation boundary like `apexes.\"Sometimes`).\n if (startChar > 0) {\n const MAX_SCAN_WORDS = 8;\n let scanPos = startChar;\n for (let scan = 0; scan < MAX_SCAN_WORDS; scan++) {\n // Advance past current word\n while (scanPos < partText.length && !/\\s/.test(partText[scanPos]))\n scanPos++;\n // Advance past whitespace to next word\n while (scanPos < partText.length && /\\s/.test(partText[scanPos]))\n scanPos++;\n if (scanPos >= partText.length) break;\n\n const retryPos = findSpokenPositionInUnspoken(\n spokenText,\n partText,\n scanPos\n );\n const scanWsEnd = skipWhitespace(partText, scanPos);\n if (retryPos > scanWsEnd) {\n cursor.currentCharIndex = retryPos;\n if (retryPos >= partText.length) {\n cursor.partFinalFlags[cursor.currentPartIndex] = true;\n if (cursor.currentPartIndex < parts.length - 1) {\n cursor.currentPartIndex++;\n cursor.currentCharIndex = 0;\n }\n }\n return true;\n }\n }\n }\n\n // Mismatch recovery: try to find the spoken text in a later part.\n for (\n let nextPartIdx = cursor.currentPartIndex + 1;\n nextPartIdx < parts.length;\n nextPartIdx++\n ) {\n const nextPart = parts[nextPartIdx];\n if (typeof nextPart.text !== \"string\") continue;\n\n const match = findSpokenPositionInUnspoken(spokenText, nextPart.text, 0);\n const nextWhitespaceEnd = skipWhitespace(nextPart.text, 0);\n if (match > nextWhitespaceEnd) {\n // Mark skipped parts as final and jump to the matched part\n for (let i = cursor.currentPartIndex; i < nextPartIdx; i++) {\n cursor.partFinalFlags[i] = true;\n }\n cursor.currentPartIndex = nextPartIdx;\n cursor.currentCharIndex = match;\n return true;\n }\n }\n\n // If we're stuck at the start, mark the current part as skipped to avoid deadlock.\n if (startChar === 0 && cursor.currentPartIndex < parts.length - 1) {\n cursor.partFinalFlags[cursor.currentPartIndex] = true;\n cursor.currentPartIndex++;\n cursor.currentCharIndex = 0;\n return true;\n }\n\n return false;\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { atom } from \"jotai\";\n\nimport type { BotOutputMessageCursor } from \"./botOutput\";\nimport type { ConversationMessage } from \"./types\";\n\n/** Raw (pre-normalization) message list */\nexport const messagesAtom = atom<ConversationMessage[]>([]);\n\n/** Tracks speech-progress cursor per message (keyed by message createdAt) */\nexport const botOutputMessageStateAtom = atom<\n Map<string, BotOutputMessageCursor>\n>(new Map());\n\n/** Callback set registered per hook instance */\nexport type MessageCallbacks = {\n onMessageCreated?: (message: ConversationMessage) => void;\n onMessageUpdated?: (message: ConversationMessage) => void;\n};\n\n/** Registered callbacks invoked on message lifecycle events */\nexport const messageCallbacksAtom = atom<Map<string, MessageCallbacks>>(\n new Map()\n);\n\n/** Whether BotOutput events are supported (RTVI 1.1.0+): null = unknown, true/false = detected */\nexport const botOutputSupportedAtom = atom<boolean | null>(null);\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\n// ES2020-compatible polyfills for findLast / findLastIndex\n\nexport function findLastIndex<T>(\n arr: T[],\n predicate: (value: T, index: number, array: T[]) => boolean\n): number {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (predicate(arr[i], i, arr)) return i;\n }\n return -1;\n}\n\nexport function findLast<T>(\n arr: T[],\n predicate: (value: T, index: number, array: T[]) => boolean\n): T | undefined {\n const idx = findLastIndex(arr, predicate);\n return idx === -1 ? undefined : arr[idx];\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport {\n BotOutputData,\n BotReadyData,\n type LLMFunctionCallInProgressData,\n type LLMFunctionCallStartedData,\n type LLMFunctionCallStoppedData,\n RTVIEvent,\n} from \"@pipecat-ai/client-js\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport { useRTVIClientEvent } from \"../useRTVIClientEvent\";\nimport { hasUnspokenContent } from \"./botOutput\";\nimport {\n addMessage,\n clearMessages,\n finalizeLastMessage,\n handleFunctionCallInProgress,\n handleFunctionCallStarted,\n handleFunctionCallStopped,\n removeEmptyLastMessage,\n updateAssistantBotOutput,\n updateLastMessage,\n upsertUserTranscript,\n} from \"./conversationActions\";\nimport {\n botOutputMessageStateAtom,\n botOutputSupportedAtom,\n messagesAtom,\n} from \"./conversationAtoms\";\nimport type { ConversationMessage } from \"./types\";\nimport { findLast, findLastIndex } from \"./utils\";\n\n/**\n * Checks if a version meets a minimum version requirement.\n * Inlined to avoid adding a `semver` dependency.\n */\nfunction isMinVersion(\n currentVersion: string,\n minVersion: [number, number, number]\n): boolean {\n // Strip pre-release suffix (e.g. \"1.1.0-beta.1\" -> \"1.1.0\")\n const parts = currentVersion.split(\"-\")[0].split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((parts[i] || 0) > minVersion[i]) return true;\n if ((parts[i] || 0) < minVersion[i]) return false;\n }\n return true; // equal\n}\n\n/** Delay (ms) before finalizing the assistant message after bot stops speaking. */\nconst BOT_STOPPED_FINALIZE_DELAY_MS = 2500;\n\n/**\n * Internal hook that wires RTVI events to conversation state atoms.\n * Called once inside PipecatConversationProvider.\n */\nexport function useConversationEventWiring() {\n const userStoppedTimeout = useRef<ReturnType<typeof setTimeout>>(undefined);\n const botStoppedSpeakingTimeoutRef =\n useRef<ReturnType<typeof setTimeout>>(undefined);\n const assistantStreamResetRef = useRef<number>(0);\n const botOutputLastChunkRef = useRef<{ spoken: string; unspoken: string }>({\n spoken: \"\",\n unspoken: \"\",\n });\n\n // Clean up pending timeouts on unmount\n useEffect(() => {\n return () => {\n clearTimeout(userStoppedTimeout.current);\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n };\n }, []);\n\n // -- helpers ---------------------------------------------------------------\n\n const finalizeLastAssistantMessageIfPending = useAtomCallback(\n useCallback((get, set) => {\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n botStoppedSpeakingTimeoutRef.current = undefined;\n const messages = get(messagesAtom);\n const lastAssistant = findLast(messages,\n (m: ConversationMessage) => m.role === \"assistant\"\n );\n if (lastAssistant && !lastAssistant.final) {\n finalizeLastMessage(get, set, \"assistant\");\n }\n }, [])\n );\n\n const ensureAssistantMessage = useAtomCallback(\n useCallback((get, set) => {\n const messages = get(messagesAtom);\n const lastAssistantIndex = findLastIndex(messages,\n (msg: ConversationMessage) => msg.role === \"assistant\"\n );\n const lastAssistant =\n lastAssistantIndex !== -1 ? messages[lastAssistantIndex] : undefined;\n\n if (!lastAssistant || lastAssistant.final) {\n // If the message was finalized but still has unspoken content, it was\n // finalized prematurely (e.g. BotStoppedSpeaking timer fired during a\n // TTS pause mid-response). Un-finalize it instead of creating a new\n // message bubble — but only when no user message followed.\n if (\n lastAssistant?.final &&\n lastAssistantIndex === messages.length - 1\n ) {\n const messageId = lastAssistant.createdAt;\n const botOutputState = get(botOutputMessageStateAtom);\n const cursor = botOutputState.get(messageId);\n if (\n cursor &&\n hasUnspokenContent(cursor, lastAssistant.parts || [])\n ) {\n updateLastMessage(get, set, \"assistant\", { final: false });\n return false;\n }\n }\n\n addMessage(get, set, {\n role: \"assistant\",\n final: false,\n parts: [],\n });\n assistantStreamResetRef.current += 1;\n return true;\n }\n return false;\n }, [])\n );\n\n // -- event handlers --------------------------------------------------------\n\n useRTVIClientEvent(\n RTVIEvent.Connected,\n useAtomCallback(\n useCallback((get, set) => {\n clearMessages(get, set);\n set(botOutputSupportedAtom, null);\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n botStoppedSpeakingTimeoutRef.current = undefined;\n botOutputLastChunkRef.current = { spoken: \"\", unspoken: \"\" };\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.BotReady,\n useAtomCallback(\n useCallback((_get, set, botData: BotReadyData) => {\n const rtviVersion = botData.version;\n const supportsBotOutput = isMinVersion(rtviVersion, [1, 1, 0]);\n set(botOutputSupportedAtom, supportsBotOutput);\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.BotOutput,\n useAtomCallback(\n useCallback(\n (get, set, data: BotOutputData) => {\n // A BotOutput event means the response is still active; cancel any\n // pending finalize timer from BotStoppedSpeaking.\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n botStoppedSpeakingTimeoutRef.current = undefined;\n\n ensureAssistantMessage();\n\n // Handle spacing for BotOutput chunks\n let textToAdd = data.text;\n const lastChunk = data.spoken\n ? botOutputLastChunkRef.current.spoken\n : botOutputLastChunkRef.current.unspoken;\n\n // Add space separator if needed between BotOutput chunks\n if (lastChunk) {\n textToAdd = \" \" + textToAdd;\n }\n\n // Update the appropriate last chunk tracker\n if (data.spoken) {\n botOutputLastChunkRef.current.spoken = textToAdd;\n } else {\n botOutputLastChunkRef.current.unspoken = textToAdd;\n }\n\n // Update both spoken and unspoken text streams\n const isFinal = data.aggregated_by === \"sentence\";\n updateAssistantBotOutput(\n get,\n set,\n textToAdd,\n isFinal,\n data.spoken,\n data.aggregated_by\n );\n },\n [ensureAssistantMessage]\n )\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.BotStoppedSpeaking,\n useAtomCallback(\n useCallback((get, set) => {\n // Don't finalize immediately; start a timer. Bot may start speaking again (pause).\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n const messages = get(messagesAtom);\n const lastAssistant = findLast(messages,\n (m: ConversationMessage) => m.role === \"assistant\"\n );\n if (!lastAssistant || lastAssistant.final) return;\n botStoppedSpeakingTimeoutRef.current = setTimeout(() => {\n botStoppedSpeakingTimeoutRef.current = undefined;\n\n // Snap the speech-progress cursor to the end of all parts.\n // The bot finished speaking normally (not interrupted), so all\n // text should render as \"spoken\". Without this, text from the\n // last sentence can remain grey if the spoken BotOutput event\n // didn't match the unspoken text exactly.\n const msgs = get(messagesAtom);\n const cursorMap = new Map(get(botOutputMessageStateAtom));\n const last = findLast(msgs,\n (m: ConversationMessage) => m.role === \"assistant\"\n );\n if (last) {\n const cursor = cursorMap.get(last.createdAt);\n if (cursor && last.parts && last.parts.length > 0) {\n const lastPartIdx = last.parts.length - 1;\n const lastPartText = last.parts[lastPartIdx]?.text;\n cursor.currentPartIndex = lastPartIdx;\n cursor.currentCharIndex =\n typeof lastPartText === \"string\" ? lastPartText.length : 0;\n for (let i = 0; i <= lastPartIdx; i++) {\n cursor.partFinalFlags[i] = true;\n }\n set(botOutputMessageStateAtom, cursorMap);\n }\n }\n\n finalizeLastMessage(get, set, \"assistant\");\n }, BOT_STOPPED_FINALIZE_DELAY_MS);\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.BotStartedSpeaking,\n useCallback(() => {\n // Bot is speaking again; reset the finalize timer (bot was just pausing).\n clearTimeout(botStoppedSpeakingTimeoutRef.current);\n botStoppedSpeakingTimeoutRef.current = undefined;\n }, [])\n );\n\n useRTVIClientEvent(\n RTVIEvent.UserStartedSpeaking,\n useAtomCallback(\n useCallback(\n (get, set) => {\n // User started a new turn; bot's turn is done. Fast-forward: finalize immediately.\n finalizeLastAssistantMessageIfPending();\n clearTimeout(userStoppedTimeout.current);\n\n // Only finalize the previous user message if the bot has responded since\n // the user last spoke. This prevents finalizing during VAD gaps (brief\n // breathing pauses within the same user turn where UserStoppedSpeaking/\n // UserStartedSpeaking fire without an actual turn change).\n const messages = get(messagesAtom);\n const lastUserIdx = findLastIndex(\n messages,\n (m: ConversationMessage) => m.role === \"user\"\n );\n if (lastUserIdx !== -1 && !messages[lastUserIdx].final) {\n const hasBotActivityAfterUser = messages\n .slice(lastUserIdx + 1)\n .some((m: ConversationMessage) => m.role === \"assistant\");\n if (hasBotActivityAfterUser) {\n finalizeLastMessage(get, set, \"user\");\n }\n }\n },\n [finalizeLastAssistantMessageIfPending]\n )\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.UserTranscript,\n useAtomCallback(\n useCallback((get, set, data) => {\n const text = data.text ?? \"\";\n const final = Boolean(data.final);\n upsertUserTranscript(get, set, text, final);\n\n // If we got any transcript, cancel pending cleanup\n clearTimeout(userStoppedTimeout.current);\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.UserStoppedSpeaking,\n useAtomCallback(\n useCallback((get, set) => {\n clearTimeout(userStoppedTimeout.current);\n // If no transcript ends up arriving, ensure any accidental empty placeholder is removed.\n userStoppedTimeout.current = setTimeout(() => {\n // Re-read state at timeout time\n const messages = get(messagesAtom);\n const lastUser = findLast(messages,\n (m: ConversationMessage) => m.role === \"user\"\n );\n const hasParts =\n Array.isArray(lastUser?.parts) && lastUser!.parts.length > 0;\n if (!lastUser || !hasParts) {\n removeEmptyLastMessage(get, set, \"user\");\n } else if (!lastUser.final) {\n finalizeLastMessage(get, set, \"user\");\n }\n }, 3000);\n }, [])\n )\n );\n\n // LLM Function Call lifecycle events\n useRTVIClientEvent(\n RTVIEvent.LLMFunctionCallStarted,\n useAtomCallback(\n useCallback((get, set, data: LLMFunctionCallStartedData) => {\n handleFunctionCallStarted(get, set, {\n function_name: data.function_name,\n });\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.LLMFunctionCallInProgress,\n useAtomCallback(\n useCallback((get, set, data: LLMFunctionCallInProgressData) => {\n handleFunctionCallInProgress(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n args: data.arguments,\n });\n }, [])\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.LLMFunctionCallStopped,\n useAtomCallback(\n useCallback((get, set, data: LLMFunctionCallStoppedData) => {\n handleFunctionCallStopped(get, set, {\n function_name: data.function_name,\n tool_call_id: data.tool_call_id,\n result: data.result,\n cancelled: data.cancelled,\n });\n }, [])\n )\n );\n}\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, RTVIEventHandler } from \"@pipecat-ai/client-js\";\nimport { useContext, useEffect } from \"react\";\n\nimport { RTVIEventContext } from \"./RTVIEventContext\";\n\nexport const useRTVIClientEvent = <E extends RTVIEvent>(\n event: E,\n handler: RTVIEventHandler<E>\n) => {\n const { on, off } = useContext(RTVIEventContext);\n\n useEffect(() => {\n on(event, handler);\n return () => {\n off(event, handler);\n };\n }, [event, handler, on, off]);\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\nimport { RTVIEvent, RTVIEventHandler } from \"@pipecat-ai/client-js\";\nimport { createContext } from \"react\";\n\nexport const RTVIEventContext = createContext<{\n on: <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => void;\n off: <E extends RTVIEvent>(event: E, handler: RTVIEventHandler<E>) => void;\n}>({\n on: () => {},\n off: () => {},\n});\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, TransportState } from \"@pipecat-ai/client-js\";\nimport React, { createContext, useCallback, useState } from \"react\";\n\nimport { usePipecatClient } from \"./usePipecatClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\nexport const PipecatClientCamStateContext = createContext<{\n enableCam: (enabled: boolean) => void;\n isCamEnabled: boolean;\n}>({\n enableCam: () => {\n throw new Error(\n \"PipecatClientCamStateContext: enableCam() called outside of provider\"\n );\n },\n isCamEnabled: false,\n});\nexport const PipecatClientMicStateContext = createContext<{\n enableMic: (enabled: boolean) => void;\n isMicEnabled: boolean;\n}>({\n enableMic: () => {\n throw new Error(\n \"PipecatClientMicStateContext: enableMic() called outside of provider\"\n );\n },\n isMicEnabled: false,\n});\nexport const PipecatClientScreenShareStateContext = createContext<{\n enableScreenShare: (enabled: boolean) => void;\n isScreenShareEnabled: boolean;\n}>({\n enableScreenShare: () => {\n throw new Error(\n \"PipecatClientScreenShareStateContext: enableScreenShare() called outside of provider\"\n );\n },\n isScreenShareEnabled: false,\n});\nexport const PipecatClientTransportStateContext =\n createContext<TransportState>(\"disconnected\");\n\nexport const PipecatClientStateProvider: React.FC<React.PropsWithChildren> = ({\n children,\n}) => {\n const client = usePipecatClient();\n const [isCamEnabled, setIsCamEnabled] = useState(false);\n const [isMicEnabled, setIsMicEnabled] = useState(false);\n const [isScreenShareEnabled, setIsScreenShareEnabled] = useState(false);\n const [transportState, setTransportState] =\n useState<TransportState>(\"disconnected\");\n\n useRTVIClientEvent(RTVIEvent.TransportStateChanged, (state) => {\n setTransportState(state);\n if (state === \"initialized\" && client) {\n setIsCamEnabled(client.isCamEnabled ?? false);\n setIsMicEnabled(client.isMicEnabled ?? false);\n setIsScreenShareEnabled(client.isSharingScreen ?? false);\n }\n });\n\n const enableCam = useCallback(\n (enabled: boolean) => {\n setIsCamEnabled(enabled);\n client?.enableCam?.(enabled);\n },\n [client]\n );\n\n const enableMic = useCallback(\n (enabled: boolean) => {\n setIsMicEnabled(enabled);\n client?.enableMic?.(enabled);\n },\n [client]\n );\n\n const enableScreenShare = useCallback(\n (enabled: boolean) => {\n client?.enableScreenShare?.(enabled);\n },\n [client]\n );\n\n useRTVIClientEvent(RTVIEvent.ScreenTrackStarted, (_track, participant) => {\n if (participant?.local) {\n setIsScreenShareEnabled(true);\n }\n });\n\n useRTVIClientEvent(RTVIEvent.ScreenTrackStopped, (_track, participant) => {\n if (participant?.local) {\n setIsScreenShareEnabled(false);\n }\n });\n\n return (\n <PipecatClientTransportStateContext.Provider value={transportState}>\n <PipecatClientCamStateContext.Provider\n value={{ enableCam, isCamEnabled }}\n >\n <PipecatClientMicStateContext.Provider\n value={{ enableMic, isMicEnabled }}\n >\n <PipecatClientScreenShareStateContext.Provider\n value={{ enableScreenShare, isScreenShareEnabled }}\n >\n {children}\n </PipecatClientScreenShareStateContext.Provider>\n </PipecatClientMicStateContext.Provider>\n </PipecatClientCamStateContext.Provider>\n </PipecatClientTransportStateContext.Provider>\n );\n};\n","import React, { useCallback } from \"react\";\n\nimport { usePipecatClientCamControl } from \"./usePipecatClientCamControl\";\n\nexport interface PipecatClientCamToggleProps {\n /**\n * Callback fired when camera state changes\n */\n onCamEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the cam toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isCamEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling camera state\n */\nexport const PipecatClientCamToggle: React.FC<PipecatClientCamToggleProps> = ({\n onCamEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { isCamEnabled, enableCam } = usePipecatClientCamControl();\n\n const handleToggleCam = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isCamEnabled;\n enableCam(newEnabledState);\n onCamEnabledChanged?.(newEnabledState);\n }, [disabled, enableCam, isCamEnabled, onCamEnabledChanged]);\n\n return (\n <>\n {children({\n isCamEnabled,\n onClick: handleToggleCam,\n disabled,\n })}\n </>\n );\n};\n\nexport default PipecatClientCamToggle;\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\nimport { useContext } from \"react\";\n\nimport { PipecatClientCamStateContext } from \"./PipecatClientState\";\n\n/**\n * Hook to control camera state\n */\nexport const usePipecatClientCamControl = () =>\n useContext(PipecatClientCamStateContext);\n","import React, { useCallback } from \"react\";\n\nimport { usePipecatClientMicControl } from \"./usePipecatClientMicControl\";\n\nexport interface PipecatClientMicToggleProps {\n /**\n * Callback fired when microphone state changes\n */\n onMicEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the mic toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isMicEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling microphone state\n */\nexport const PipecatClientMicToggle: React.FC<PipecatClientMicToggleProps> = ({\n onMicEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { enableMic, isMicEnabled } = usePipecatClientMicControl();\n\n const handleToggleMic = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isMicEnabled;\n enableMic(newEnabledState);\n onMicEnabledChanged?.(newEnabledState);\n }, [disabled, enableMic, isMicEnabled, onMicEnabledChanged]);\n\n return (\n <>\n {children({\n isMicEnabled,\n onClick: handleToggleMic,\n disabled,\n })}\n </>\n );\n};\n\nexport default PipecatClientMicToggle;\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { PipecatClientMicStateContext } from \"./PipecatClientState\";\n\n/**\n * Hook to control microphone state\n */\nexport const usePipecatClientMicControl = () =>\n useContext(PipecatClientMicStateContext);\n","/**\n * Copyright (c) 2025, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { useCallback, useEffect } from \"react\";\n\nimport { usePipecatClientScreenShareControl } from \"./usePipecatClientScreenShareControl\";\n\nexport interface PipecatClientScreenShareToggleProps {\n /**\n * Callback when screen share state changes\n */\n onScreenShareEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the screen share toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isScreenShareEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling screen share state\n */\nexport const PipecatClientScreenShareToggle: React.FC<\n PipecatClientScreenShareToggleProps\n> = ({ onScreenShareEnabledChanged, disabled = false, children }) => {\n const { enableScreenShare, isScreenShareEnabled } =\n usePipecatClientScreenShareControl();\n\n const handleToggleScreenShare = useCallback(() => {\n if (disabled) return;\n enableScreenShare(!isScreenShareEnabled);\n }, [disabled, enableScreenShare, isScreenShareEnabled]);\n\n useEffect(() => {\n onScreenShareEnabledChanged?.(isScreenShareEnabled);\n }, [isScreenShareEnabled, onScreenShareEnabledChanged]);\n\n return (\n <>\n {children({\n isScreenShareEnabled,\n onClick: handleToggleScreenShare,\n disabled,\n })}\n </>\n );\n};\n\nexport default PipecatClientScreenShareToggle;\n","/**\n * Copyright (c) 2025, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { PipecatClientScreenShareStateContext } from \"./PipecatClientState\";\n\n/**\n * Hook to control screen share state using React Context\n * This provides a simpler interface for basic screen share control\n * For more advanced state management with Jotai atoms, use usePipecatClientScreenShare\n */\nexport const usePipecatClientScreenShareControl = () =>\n useContext(PipecatClientScreenShareStateContext);\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { forwardRef, useEffect, useRef } from \"react\";\n\nimport useMergedRef from \"./useMergedRef\";\nimport { usePipecatClientMediaTrack } from \"./usePipecatClientMediaTrack\";\n\ninterface PipecatClientVideoInterface {\n aspectRatio: number;\n height: number;\n width: number;\n}\n\nexport interface Props extends Omit<\n React.VideoHTMLAttributes<HTMLVideoElement>,\n \"onResize\"\n> {\n participant: \"local\" | \"bot\";\n\n /**\n * Defines the video track type to display. Default: 'video'.\n */\n trackType?: \"screenVideo\" | \"video\";\n\n /**\n * Defines whether the video should be fully contained or cover the box. Default: 'contain'.\n */\n fit?: \"contain\" | \"cover\";\n /**\n * Forces the video to be mirrored, if set.\n */\n mirror?: boolean;\n\n /**\n * Optional callback, which is triggered whenever the video's rendered width or height changes.\n * Returns the video's native width, height and aspectRatio.\n */\n onResize?(dimensions: PipecatClientVideoInterface): void;\n}\n\nexport const PipecatClientVideo = forwardRef<HTMLVideoElement, Props>(\n function VoiceClientVideo(\n {\n participant = \"local\",\n fit = \"contain\",\n mirror,\n onResize,\n style = {},\n trackType = \"video\",\n ...props\n },\n ref\n ) {\n const videoTrack: MediaStreamTrack | null = usePipecatClientMediaTrack(\n trackType,\n participant\n );\n\n const videoEl = useRef<HTMLVideoElement>(null);\n const videoRef = useMergedRef<HTMLVideoElement>(videoEl, ref);\n\n /**\n * Handle canplay & picture-in-picture events.\n */\n useEffect(function setupVideoEvents() {\n const video = videoEl.current;\n if (!video) return;\n\n const playVideo = () => {\n const promise = video.play();\n if (promise !== undefined) {\n promise\n .then(() => {\n // All good, playback started.\n video.controls = false;\n })\n .catch((error) => {\n // Auto-play was prevented. Show video controls, so user can play video manually.\n video.controls = true;\n console.warn(\"Failed to play video\", error);\n });\n }\n };\n\n const handleCanPlay = () => {\n if (!video.paused) return;\n playVideo();\n };\n const handleEnterPIP = () => {\n video.style.transform = \"scale(1)\";\n };\n const handleLeavePIP = () => {\n video.style.transform = \"\";\n setTimeout(() => {\n if (video.paused) playVideo();\n }, 100);\n };\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") return;\n if (!video.paused) return;\n playVideo();\n };\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.addEventListener(\"leavepictureinpicture\", handleLeavePIP);\n\n // Videos can be paused if media was played in another app on iOS.\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n return () => {\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.removeEventListener(\"leavepictureinpicture\", handleLeavePIP);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n };\n }, []);\n\n /**\n * Update srcObject.\n */\n useEffect(\n function updateSrcObject() {\n const video = videoEl.current;\n if (!video || !videoTrack) return;\n video.srcObject = new MediaStream([videoTrack]);\n video.load();\n return () => {\n // clean up when unmounted\n video.srcObject = null;\n video.load();\n };\n },\n [videoTrack, videoTrack?.id]\n );\n\n /**\n * Add optional event listener for resize event so the parent component\n * can know the video's native aspect ratio.\n */\n useEffect(\n function reportVideoDimensions() {\n const video = videoEl.current;\n if (!onResize || !video) return;\n\n let frame: ReturnType<typeof requestAnimationFrame>;\n function handleResize() {\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n const video = videoEl.current;\n if (!video || document.hidden) return;\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n if (videoWidth && videoHeight) {\n onResize?.({\n aspectRatio: videoWidth / videoHeight,\n height: videoHeight,\n width: videoWidth,\n });\n }\n });\n }\n\n handleResize();\n video.addEventListener(\"loadedmetadata\", handleResize);\n video.addEventListener(\"resize\", handleResize);\n\n return () => {\n if (frame) cancelAnimationFrame(frame);\n video.removeEventListener(\"loadedmetadata\", handleResize);\n video.removeEventListener(\"resize\", handleResize);\n };\n },\n [onResize]\n );\n\n return (\n <video\n autoPlay\n muted\n playsInline\n ref={videoRef}\n style={{\n objectFit: fit,\n transform: mirror ? \"scale(-1, 1)\" : \"\",\n ...style,\n }}\n {...props}\n />\n );\n }\n);\nPipecatClientVideo.displayName = \"PipecatClientVideo\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n *\n * This file contains code derived from:\n * https://github.com/jaredLunde/react-hook/blob/master/packages/merged-ref/src/index.tsx\n * Original author: Jared Lunde (https://github.com/jaredLunde)\n * Original license: MIT (https://github.com/jaredLunde/react-hook/blob/master/LICENSE)\n */\n\nimport React, { useCallback } from \"react\";\n\nfunction useMergedRef<T>(...refs: React.Ref<T>[]): React.RefCallback<T> {\n return useCallback(\n (element: T) => {\n for (let i = 0; i < refs.length; i++) {\n const ref = refs[i];\n if (typeof ref === \"function\") ref(element);\n else if (ref && typeof ref === \"object\")\n (ref as React.MutableRefObject<T>).current = element;\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n refs\n );\n}\n\nexport default useMergedRef;\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\nimport { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { usePipecatClient } from \"./usePipecatClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype OptionalMediaDeviceInfo = MediaDeviceInfo | Record<string, never>;\n\nconst availableMicsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableCamsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableSpeakersAtom = atom<MediaDeviceInfo[]>([]);\nconst selectedMicAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedCamAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedSpeakerAtom = atom<OptionalMediaDeviceInfo>({});\n\nexport const usePipecatClientMediaDevices = () => {\n const client = usePipecatClient();\n\n const availableCams = useAtomValue(availableCamsAtom);\n const availableMics = useAtomValue(availableMicsAtom);\n const availableSpeakers = useAtomValue(availableSpeakersAtom);\n const selectedCam = useAtomValue(selectedCamAtom);\n const selectedMic = useAtomValue(selectedMicAtom);\n const selectedSpeaker = useAtomValue(selectedSpeakerAtom);\n\n const initDevices = useAtomCallback(\n useCallback(\n async (_get, set) => {\n if (!client) return;\n\n const availableCams = await client.getAllCams();\n const availableMics = await client.getAllMics();\n const availableSpeakers = await client.getAllSpeakers();\n\n set(availableCamsAtom, availableCams);\n set(availableMicsAtom, availableMics);\n set(availableSpeakersAtom, availableSpeakers);\n\n set(selectedCamAtom, client.selectedCam);\n set(selectedMicAtom, client.selectedMic);\n set(selectedSpeakerAtom, client.selectedSpeaker);\n },\n [client]\n )\n );\n\n useEffect(() => {\n initDevices();\n }, [initDevices]);\n\n useRTVIClientEvent(\n RTVIEvent.AvailableCamsUpdated,\n useAtomCallback(\n useCallback((_get, set, cams) => {\n set(availableCamsAtom, cams);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableMicsUpdated,\n useAtomCallback(\n useCallback((_get, set, mics) => {\n set(availableMicsAtom, mics);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableSpeakersUpdated,\n useAtomCallback(\n useCallback((_get, set, speakers) => {\n set(availableSpeakersAtom, speakers);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.CamUpdated,\n useAtomCallback(\n useCallback((_get, set, cam) => {\n set(selectedCamAtom, cam);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.MicUpdated,\n useAtomCallback(\n useCallback((_get, set, mic) => {\n set(selectedMicAtom, mic);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useAtomCallback(\n useCallback((_get, set, speaker) => {\n set(selectedSpeakerAtom, speaker);\n }, [])\n )\n );\n\n const updateCam = useCallback(\n (id: string) => {\n client?.updateCam(id);\n },\n [client]\n );\n const updateMic = useCallback(\n (id: string) => {\n client?.updateMic(id);\n },\n [client]\n );\n const updateSpeaker = useCallback(\n (id: string) => {\n client?.updateSpeaker(id);\n },\n [client]\n );\n\n return {\n availableCams,\n availableMics,\n availableSpeakers,\n selectedCam,\n selectedMic,\n selectedSpeaker,\n updateCam,\n updateMic,\n updateSpeaker,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { PipecatClientTransportStateContext } from \"./PipecatClientState\";\n\nexport const usePipecatClientTransportState = () =>\n useContext(PipecatClientTransportStateContext);\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { useEffect, useRef } from \"react\";\n\nimport { usePipecatClientMediaTrack } from \"./usePipecatClientMediaTrack\";\n\ntype ParticipantType = Parameters<typeof usePipecatClientMediaTrack>[1];\n\ninterface Props {\n backgroundColor?: string;\n barColor?: string;\n barCount?: number;\n barGap?: number;\n barLineCap?: \"round\" | \"square\";\n barMaxHeight?: number;\n barOrigin?: \"top\" | \"bottom\" | \"center\";\n barWidth?: number;\n participantType: ParticipantType;\n}\n\nexport const VoiceVisualizer: React.FC<Props> = React.memo(\n ({\n backgroundColor = \"transparent\",\n barColor = \"black\",\n barCount = 5,\n barGap = 12,\n barLineCap = \"round\",\n barMaxHeight = 120,\n barOrigin = \"center\",\n barWidth = 30,\n participantType,\n }) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const track: MediaStreamTrack | null = usePipecatClientMediaTrack(\n \"audio\",\n participantType\n );\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const canvasWidth = barCount * barWidth + (barCount - 1) * barGap;\n const canvasHeight = barMaxHeight;\n\n const canvas = canvasRef.current;\n\n const scaleFactor = 2;\n\n // Make canvas fill the width and height of its container\n const resizeCanvas = () => {\n canvas.width = canvasWidth * scaleFactor;\n canvas.height = canvasHeight * scaleFactor;\n\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n\n canvasCtx.lineCap = barLineCap;\n canvasCtx.scale(scaleFactor, scaleFactor);\n };\n\n const canvasCtx = canvas.getContext(\"2d\")!;\n resizeCanvas();\n\n if (!track) return;\n\n const audioContext = new AudioContext();\n const source = audioContext.createMediaStreamSource(\n new MediaStream([track])\n );\n const analyser = audioContext.createAnalyser();\n\n analyser.fftSize = 1024;\n\n source.connect(analyser);\n\n const frequencyData = new Uint8Array(analyser.frequencyBinCount);\n\n canvasCtx.lineCap = barLineCap;\n\n // Create frequency bands based on barCount\n const bands = Array.from({ length: barCount }, (_, i) => {\n // Use improved logarithmic scale for better frequency distribution\n const minFreq = barCount > 20 ? 200 : 80; // Adjust min frequency based on bar count\n const maxFreq = 10000; // Cover most important audio frequencies\n\n // Use Mel scale inspired approach for more perceptually uniform distribution\n // This helps with a large number of bars by placing fewer in the very low range\n // https://en.wikipedia.org/wiki/Mel_scale\n const melMin = 2595 * Math.log10(1 + minFreq / 700);\n const melMax = 2595 * Math.log10(1 + maxFreq / 700);\n const melStep = (melMax - melMin) / barCount;\n\n const melValue = melMin + i * melStep;\n const startFreq = 700 * (Math.pow(10, melValue / 2595) - 1);\n const endFreq = 700 * (Math.pow(10, (melValue + melStep) / 2595) - 1);\n\n return {\n startFreq,\n endFreq,\n smoothValue: 0,\n };\n });\n\n const getFrequencyBinIndex = (frequency: number) => {\n const nyquist = audioContext.sampleRate / 2;\n return Math.round(\n (frequency / nyquist) * (analyser.frequencyBinCount - 1)\n );\n };\n\n function drawSpectrum() {\n analyser.getByteFrequencyData(frequencyData);\n canvasCtx.clearRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n canvasCtx.fillStyle = backgroundColor;\n canvasCtx.fillRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n\n let isActive = false;\n\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2; // Center bars\n\n const adjustedCircleRadius = barWidth / 2; // Fixed radius for reset circles\n\n bands.forEach((band, i) => {\n const startIndex = getFrequencyBinIndex(band.startFreq);\n const endIndex = getFrequencyBinIndex(band.endFreq);\n const bandData = frequencyData.slice(startIndex, endIndex);\n const bandValue =\n bandData.reduce((acc, val) => acc + val, 0) / bandData.length;\n\n const smoothingFactor = 0.2;\n\n if (bandValue < 1) {\n band.smoothValue = Math.max(\n band.smoothValue - smoothingFactor * 5,\n 0\n );\n } else {\n band.smoothValue =\n band.smoothValue +\n (bandValue - band.smoothValue) * smoothingFactor;\n isActive = true;\n }\n\n const x = startX + i * (barWidth + barGap);\n // Calculate bar height with a maximum cap\n const minHeight = 0;\n const barHeight = Math.max(\n minHeight,\n Math.min((band.smoothValue / 255) * barMaxHeight, barMaxHeight)\n );\n\n let yTop, yBottom;\n const canvasHeight = canvas.height / scaleFactor;\n\n switch (barOrigin) {\n case \"top\":\n yTop = adjustedCircleRadius;\n yBottom = Math.min(\n adjustedCircleRadius + barHeight,\n canvasHeight - adjustedCircleRadius\n );\n break;\n case \"bottom\":\n yBottom = canvasHeight - adjustedCircleRadius;\n yTop = Math.max(yBottom - barHeight, adjustedCircleRadius);\n break;\n case \"center\":\n default:\n yTop = Math.max(\n canvasHeight / 2 - barHeight / 2,\n adjustedCircleRadius\n );\n yBottom = Math.min(\n canvasHeight / 2 + barHeight / 2,\n canvasHeight - adjustedCircleRadius\n );\n break;\n }\n\n if (band.smoothValue > 0) {\n canvasCtx.beginPath();\n canvasCtx.moveTo(x + barWidth / 2, yTop);\n canvasCtx.lineTo(x + barWidth / 2, yBottom);\n canvasCtx.lineWidth = barWidth;\n canvasCtx.strokeStyle = barColor;\n canvasCtx.stroke();\n } else {\n drawInactiveCircle(adjustedCircleRadius, barColor, x, yTop);\n }\n });\n\n if (!isActive) {\n drawInactiveCircles(adjustedCircleRadius, barColor);\n }\n\n requestAnimationFrame(drawSpectrum);\n }\n\n function drawInactiveCircle(\n circleRadius: number,\n color: string,\n x: number,\n y: number\n ) {\n switch (barLineCap) {\n case \"square\":\n canvasCtx.fillStyle = color;\n canvasCtx.fillRect(\n x + barWidth / 2 - circleRadius,\n y - circleRadius,\n circleRadius * 2,\n circleRadius * 2\n );\n break;\n case \"round\":\n default:\n canvasCtx.beginPath();\n canvasCtx.arc(x + barWidth / 2, y, circleRadius, 0, 2 * Math.PI);\n canvasCtx.fillStyle = color;\n canvasCtx.fill();\n canvasCtx.closePath();\n break;\n }\n }\n\n function drawInactiveCircles(circleRadius: number, color: string) {\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2;\n const canvasHeight = canvas.height / scaleFactor;\n\n let y;\n switch (barOrigin) {\n case \"top\":\n y = circleRadius;\n break;\n case \"bottom\":\n y = canvasHeight - circleRadius;\n break;\n case \"center\":\n default:\n y = canvasHeight / 2;\n break;\n }\n\n bands.forEach((_, i) => {\n const x = startX + i * (barWidth + barGap);\n drawInactiveCircle(circleRadius, color, x, y);\n });\n }\n\n drawSpectrum();\n\n // Handle resizing\n window.addEventListener(\"resize\", resizeCanvas);\n\n return () => {\n audioContext.close();\n window.removeEventListener(\"resize\", resizeCanvas);\n };\n }, [\n backgroundColor,\n barColor,\n barCount,\n barGap,\n barLineCap,\n barMaxHeight,\n barOrigin,\n barWidth,\n track,\n ]);\n\n return (\n <canvas\n ref={canvasRef}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n }}\n />\n );\n }\n);\n\nVoiceVisualizer.displayName = \"VoiceVisualizer\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect, useId, useMemo } from \"react\";\n\nimport {\n registerMessageCallback,\n unregisterMessageCallback,\n} from \"./conversation/conversationActions\";\nimport {\n botOutputMessageStateAtom,\n messagesAtom,\n} from \"./conversation/conversationAtoms\";\nimport { useConversationContext } from \"./conversation/PipecatConversationProvider\";\nimport type {\n AggregationMetadata,\n ConversationMessage,\n ConversationMessagePart,\n} from \"./conversation/types\";\n\n/**\n * Options for `usePipecatConversation`.\n */\ninterface Props {\n /**\n * Called once when a brand-new message first enters the conversation.\n * The message may or may not be complete at this point — check `message.final`.\n */\n onMessageCreated?: (message: ConversationMessage) => void;\n /**\n * Called whenever an existing message's content changes\n * (e.g. streaming text appended, function call status changed, message finalized).\n * Check `message.final` to detect finalization.\n */\n onMessageUpdated?: (message: ConversationMessage) => void;\n /**\n * @deprecated Use `onMessageCreated` instead. Will be removed in a future release.\n */\n onMessageAdded?: (message: ConversationMessage) => void;\n /**\n * Metadata for aggregation types to control rendering and speech progress behavior.\n * Used to determine which aggregations should be excluded from position-based splitting.\n */\n aggregationMetadata?: Record<string, AggregationMetadata>;\n}\n\n/**\n * React hook for accessing and subscribing to the current conversation stream.\n *\n * This hook provides:\n * - The current list of conversation messages, ordered and merged for display.\n * - An `injectMessage` function to programmatically add a message to the conversation.\n * - Lifecycle callbacks: `onMessageCreated`, `onMessageUpdated`.\n *\n * Internally, this hook:\n * - Subscribes to conversation state updates and merges/filters messages for UI consumption.\n * - Ensures the provided callbacks are registered and unregistered as the component mounts/unmounts or the callbacks change.\n *\n * @param {Props} [options] - Optional configuration for the hook.\n * @returns {{\n * messages: ConversationMessage[];\n * injectMessage: (message: { role: \"user\" | \"assistant\" | \"system\"; parts: any[] }) => void;\n * }}\n */\nexport const usePipecatConversation = ({\n onMessageCreated,\n onMessageUpdated,\n onMessageAdded,\n aggregationMetadata,\n}: Props = {}) => {\n const { injectMessage } = useConversationContext();\n\n // Generate a unique ID for this hook instance\n const callbackId = useId();\n\n // Resolve deprecated onMessageAdded → onMessageCreated\n const resolvedCreated = onMessageCreated ?? onMessageAdded;\n\n // Register and unregister the callbacks\n const doRegister = useAtomCallback(\n useCallback(\n (get, set) => {\n registerMessageCallback(get, set, callbackId, {\n onMessageCreated: resolvedCreated,\n onMessageUpdated,\n });\n },\n [callbackId, resolvedCreated, onMessageUpdated]\n )\n );\n\n const doUnregister = useAtomCallback(\n useCallback(\n (get, set) => {\n unregisterMessageCallback(get, set, callbackId);\n },\n [callbackId]\n )\n );\n\n useEffect(() => {\n doRegister();\n return () => {\n doUnregister();\n };\n }, [doRegister, doUnregister]);\n\n // Get the raw state from atoms\n const messages = useAtomValue(messagesAtom);\n const botOutputMessageState = useAtomValue(botOutputMessageStateAtom);\n\n // Memoize the filtered messages to prevent infinite loops\n const filteredMessages = useMemo(() => {\n const getMetadata = (part: ConversationMessagePart) => {\n return part.aggregatedBy\n ? aggregationMetadata?.[part.aggregatedBy]\n : undefined;\n };\n\n // Process messages: convert string parts to BotOutputText based on position state\n const processedMessages = messages.map((message) => {\n if (message.role === \"assistant\") {\n const messageId = message.createdAt;\n const messageState = botOutputMessageState.get(messageId);\n\n if (!messageState) {\n // No state yet, return message as-is\n return message;\n }\n\n const parts = message.parts || [];\n\n // Find the actual current part index (skip parts that aren't meant to be spoken)\n let actualCurrentPartIndex = messageState.currentPartIndex;\n while (actualCurrentPartIndex < parts.length) {\n const part = parts[actualCurrentPartIndex];\n if (typeof part?.text !== \"string\") break;\n const isSpoken = getMetadata(part)?.isSpoken !== false;\n if (isSpoken) break;\n actualCurrentPartIndex++;\n }\n if (parts.length > 0 && actualCurrentPartIndex >= parts.length) {\n actualCurrentPartIndex = parts.length - 1;\n }\n\n // Convert parts to BotOutputText format based on position state\n const processedParts: ConversationMessagePart[] = parts.map(\n (part, partIndex) => {\n // If part text is not a string, it's already processed (e.g., ReactNode)\n if (typeof part.text !== \"string\") return part;\n\n const metadata = getMetadata(part);\n const displayMode =\n part.displayMode ?? metadata?.displayMode ?? \"inline\";\n const isSpoken = metadata?.isSpoken !== false;\n\n const partText =\n displayMode === \"block\" && !isSpoken\n ? part.text.trim()\n : part.text;\n if (!isSpoken) {\n return {\n ...part,\n displayMode,\n text: { spoken: \"\", unspoken: partText },\n };\n }\n\n // Use cursor split for the part at actualCurrentPartIndex for every message,\n // so previous (e.g. interrupted) messages keep partially spoken state.\n const isPartAtCursor = partIndex === actualCurrentPartIndex;\n const currentCharIndex = messageState.currentCharIndex;\n const spokenText = isPartAtCursor\n ? partText.slice(0, currentCharIndex)\n : partIndex < actualCurrentPartIndex\n ? partText\n : \"\";\n const unspokenText = isPartAtCursor\n ? partText.slice(currentCharIndex)\n : partIndex < actualCurrentPartIndex\n ? \"\"\n : partText;\n\n return {\n ...part,\n displayMode,\n text: { spoken: spokenText, unspoken: unspokenText },\n };\n }\n );\n\n return {\n ...message,\n parts: processedParts,\n };\n }\n return message;\n });\n\n // Messages are already normalized (sorted, filtered, deduped, merged) on write.\n return processedMessages;\n }, [messages, botOutputMessageState, aggregationMetadata]);\n\n return {\n messages: filteredMessages,\n injectMessage,\n };\n};\n"],"names":[],"version":3,"file":"index.module.js.map"}