@bikdotai/bik-component-library 0.0.876 → 0.0.877-beta.0

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
- {"version":3,"file":"useCopilotStreamChat.js","sources":["../../../../src/components/bik-copilot/useCopilotStreamChat.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { COPILOT_REGENERATE_PROMPT } from './copilotRegenerate';\nimport {\n\tCopilotFeedbackDetail,\n\tCopilotFeedbackVote,\n\tCopilotMessage,\n\tCopilotStreamEvent,\n\tUseCopilotStreamChatOptions,\n\tUseCopilotStreamChatResult,\n} from './model';\nimport {\n\tdeleteCopilotSession,\n\tloadCopilotSession,\n\tpersistCopilotTurn,\n\tpruneCopilotSessions,\n} from './services/copilotDb';\nimport { sendCopilotFeedback } from './services/copilotFeedbackClient';\nimport {\n\tCOPILOT_HISTORY_PAGE_SIZE,\n\tfetchCopilotMessages,\n} from './services/copilotMessagesClient';\nimport {\n\tgetCopilotSessionIdForRoute,\n\tresetCopilotSessionForRoute,\n\tresolveCopilotSessionIdForRoute,\n} from './services/copilotPageSession';\nimport {\n\treadCopilotEventContent,\n\tstreamCopilotChat,\n} from './services/copilotStreamClient';\nimport {\n\tDEFAULT_COPILOT_AGENT,\n\tDEFAULT_COPILOT_ROUTE,\n} from './useCopilotIcebreakers';\n\nconst GENERIC_ERROR = 'Something went wrong. Please try again.';\n\n/**\n * Runs a merchant copilot conversation against the streaming\n * `/bik-ai/copilot-chatbot` endpoint.\n *\n * Owns three things the endpoint's contract requires:\n *\n * 1. **The session id.** One per route. Navigating away and back to the same\n * route continues that conversation, and so does a refresh: the ids live in\n * memory but are recovered from the stored records, which is what keeps them\n * lined up with the history the backend keys by them (see\n * `copilotPageSession`).\n * 2. **`previousResponseId`.** Absent on the first turn; from then on it is the\n * `responseId` of the last `TEXT` event, which is what makes OpenAI replay the\n * earlier turns server side. A turn that breaks halfway returns no\n * `responseId`, and the backend means that — the next turn starts fresh.\n * 3. **The transcript**, stored in IndexedDB under `{sessionId}:{route}` and\n * written every turn, so leaving the page mid-conversation loses nothing.\n */\nconst asRestored = (messages: CopilotMessage[]): CopilotMessage[] =>\n\tmessages.map((message) =>\n\t\tmessage.role === 'assistant' ? { ...message, isRestored: true } : message,\n\t);\n\nexport const useCopilotStreamChat = ({\n\tstoreId,\n\tagent = DEFAULT_COPILOT_AGENT,\n\troute = DEFAULT_COPILOT_ROUTE,\n\tmessagesPath,\n\tfeedbackPath,\n\tuser,\n\tloadHistory = true,\n\tsystemPrompt,\n\tsessionId: pinnedSessionId,\n\tpersist = true,\n\tonError,\n\tonResponseComplete,\n\tonSessionIdChange,\n\tbaseUrl,\n\tendpointPath,\n\theaders,\n\tauthToken,\n\tgetAuthToken,\n\tfetchImpl,\n}: UseCopilotStreamChatOptions): UseCopilotStreamChatResult => {\n\tconst [messages, setMessages] = useState<CopilotMessage[]>([]);\n\tconst [sessionId, setSessionId] = useState<string | null>(\n\t\tpinnedSessionId ?? null,\n\t);\n\tconst [isStreaming, setIsStreaming] = useState(false);\n\tconst [isRestoring, setIsRestoring] = useState(true);\n\tconst [error, setError] = useState<string | undefined>();\n\tconst [previousResponseId, setPreviousResponseId] = useState<\n\t\tstring | undefined\n\t>();\n\tconst [isLoadingHistory, setIsLoadingHistory] = useState(false);\n\tconst [hasMoreHistory, setHasMoreHistory] = useState(false);\n\n\t// Async stream handlers run long after the render that created them, so the\n\t// live values live in refs and state is only the render mirror.\n\tconst messagesRef = useRef<CopilotMessage[]>([]);\n\tconst previousResponseIdRef = useRef<string | undefined>(undefined);\n\tconst streamingIdRef = useRef<string | null>(null);\n\tconst abortRef = useRef<(() => void) | null>(null);\n\tconst sessionIdRef = useRef<string | null>(pinnedSessionId ?? null);\n\t// The active route, for the async handlers that write the transcript.\n\tconst routeRef = useRef<string>(route);\n\trouteRef.current = route;\n\t// Next page of stored history to ask for. Starts at 2 when the local cache\n\t// already holds page 1's worth, which is the steady state.\n\tconst nextHistoryPageRef = useRef(1);\n\tconst isLoadingHistoryRef = useRef(false);\n\n\tconst applyMessages = useCallback(\n\t\t(updater: (previous: CopilotMessage[]) => CopilotMessage[]) => {\n\t\t\tconst next = updater(messagesRef.current);\n\t\t\tmessagesRef.current = next;\n\t\t\tsetMessages(next);\n\t\t},\n\t\t[],\n\t);\n\n\tconst setThreadResponseId = useCallback((responseId: string | undefined) => {\n\t\tpreviousResponseIdRef.current = responseId;\n\t\tsetPreviousResponseId(responseId);\n\t}, []);\n\n\tconst save = useCallback(() => {\n\t\tconst id = sessionIdRef.current;\n\t\tif (!persist || !id) {\n\t\t\treturn;\n\t\t}\n\t\tvoid persistCopilotTurn({\n\t\t\troute: routeRef.current,\n\t\t\tsessionId: id,\n\t\t\tmessages: messagesRef.current,\n\t\t\tpreviousResponseId: previousResponseIdRef.current,\n\t\t\tstoreId,\n\t\t\tagent,\n\t\t});\n\t}, [agent, persist, storeId]);\n\n\t// Transport config for the async readers below. Held in a ref rather than in\n\t// the effect's deps: a host that passes an inline `headers` object would\n\t// otherwise re-run restore on every render and wipe the transcript.\n\tconst transportRef = useRef({\n\t\tbaseUrl,\n\t\tmessagesPath,\n\t\tfeedbackPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tloadHistory,\n\t\tuser,\n\t});\n\ttransportRef.current = {\n\t\tbaseUrl,\n\t\tmessagesPath,\n\t\tfeedbackPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tloadHistory,\n\t\tuser,\n\t};\n\n\tconst readHistoryPage = useCallback(async (page: number) => {\n\t\tconst transport = transportRef.current;\n\t\tconst id = sessionIdRef.current;\n\t\tif (!transport.loadHistory || !id) {\n\t\t\treturn null;\n\t\t}\n\t\tconst historyPage = await fetchCopilotMessages({\n\t\t\tbaseUrl: transport.baseUrl,\n\t\t\tendpointPath: transport.messagesPath,\n\t\t\theaders: transport.headers,\n\t\t\tauthToken: transport.authToken,\n\t\t\tgetAuthToken: transport.getAuthToken,\n\t\t\tfetchImpl: transport.fetchImpl,\n\t\t\tstoreId: transport.storeId,\n\t\t\tsessionId: id,\n\t\t\tpage,\n\t\t\tpageSize: COPILOT_HISTORY_PAGE_SIZE,\n\t\t});\n\t\treturn { ...historyPage, messages: asRestored(historyPage.messages) };\n\t}, []);\n\n\t// Resolve the conversation for this route and read it back from IndexedDB.\n\t// Runs again when `route` changes, because the route is half of a\n\t// conversation's identity — a different page is a different chat.\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tconst restore = async () => {\n\t\t\t// Chunks from the previous route's turn must not land in this one.\n\t\t\tabortRef.current?.();\n\t\t\tabortRef.current = null;\n\t\t\tstreamingIdRef.current = null;\n\t\t\tsetIsStreaming(false);\n\t\t\tsetError(undefined);\n\t\t\tsetIsRestoring(true);\n\t\t\tsetHasMoreHistory(false);\n\t\t\tisLoadingHistoryRef.current = false;\n\t\t\tsetIsLoadingHistory(false);\n\n\t\t\tconst id =\n\t\t\t\tpinnedSessionId ??\n\t\t\t\t(persist\n\t\t\t\t\t? await resolveCopilotSessionIdForRoute({ route, storeId })\n\t\t\t\t\t: getCopilotSessionIdForRoute({ route, storeId }));\n\t\t\tconst record = persist ? await loadCopilotSession(route, id) : null;\n\t\t\tif (cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsessionIdRef.current = id;\n\t\t\tsetSessionId(id);\n\t\t\tmessagesRef.current = asRestored(record?.messages ?? []);\n\t\t\tsetMessages(messagesRef.current);\n\t\t\tsetThreadResponseId(record?.previousResponseId);\n\t\t\tsetIsRestoring(false);\n\t\t\tonSessionIdChange?.(id);\n\n\t\t\t// The cache holds at most one page, so what is on screen already *is*\n\t\t\t// page 1 and the reader's first scroll-up wants page 2.\n\t\t\tif (messagesRef.current.length > 0) {\n\t\t\t\tnextHistoryPageRef.current = 2;\n\t\t\t\tsetHasMoreHistory(transportRef.current.loadHistory);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Nothing cached and nothing to scroll, so page 1 has to be fetched for\n\t\t\t// the history to be reachable at all — but only for an id the host\n\t\t\t// pinned. An id this library resolved came out of the local records, so\n\t\t\t// an empty cache for it means an empty conversation, and a freshly\n\t\t\t// minted one has nothing behind it by definition. Asking anyway would\n\t\t\t// put a pointless request on the start of every new conversation.\n\t\t\tif (!pinnedSessionId) {\n\t\t\t\tnextHistoryPageRef.current = 1;\n\t\t\t\tsetHasMoreHistory(false);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tnextHistoryPageRef.current = 1;\n\t\t\ttry {\n\t\t\t\tconst firstPage = await readHistoryPage(1);\n\t\t\t\tif (cancelled || !firstPage) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnextHistoryPageRef.current = 2;\n\t\t\t\tapplyMessages(() => firstPage.messages);\n\t\t\t\tsetHasMoreHistory(firstPage.hasMore);\n\t\t\t} catch {\n\t\t\t\t// A session the backend has never heard of is the normal case for a\n\t\t\t\t// host-pinned id on its first use; the empty state covers it.\n\t\t\t\tsetHasMoreHistory(false);\n\t\t\t}\n\t\t};\n\n\t\tvoid restore();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t\t// onSessionIdChange is event-like: re-running restore because the host\n\t\t// passed a new inline callback would wipe the transcript.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [\n\t\troute,\n\t\tstoreId,\n\t\tpinnedSessionId,\n\t\tpersist,\n\t\tsetThreadResponseId,\n\t\tapplyMessages,\n\t\treadHistoryPage,\n\t]);\n\n\t/**\n\t * Prepends the page before the oldest message on screen.\n\t *\n\t * Guarded by a ref rather than the state flag because a scroll handler can\n\t * fire many times before React re-renders, and each of those would otherwise\n\t * start its own request for the same page.\n\t */\n\tconst loadOlderMessages = useCallback(() => {\n\t\tif (isLoadingHistoryRef.current || !hasMoreHistory) {\n\t\t\treturn;\n\t\t}\n\t\tisLoadingHistoryRef.current = true;\n\t\tsetIsLoadingHistory(true);\n\n\t\tconst page = nextHistoryPageRef.current;\n\t\tvoid (async () => {\n\t\t\ttry {\n\t\t\t\tconst older = await readHistoryPage(page);\n\t\t\t\tif (!older) {\n\t\t\t\t\tsetHasMoreHistory(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnextHistoryPageRef.current = page + 1;\n\t\t\t\tsetHasMoreHistory(older.hasMore);\n\t\t\t\tapplyMessages((previous) => {\n\t\t\t\t\tconst known = new Set(\n\t\t\t\t\t\tprevious.flatMap((message) =>\n\t\t\t\t\t\t\tmessage.messageId\n\t\t\t\t\t\t\t\t? [message.id, message.messageId]\n\t\t\t\t\t\t\t\t: [message.id],\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\tconst fresh = older.messages.filter(\n\t\t\t\t\t\t(message) => !known.has(message.id),\n\t\t\t\t\t);\n\t\t\t\t\treturn fresh.length > 0 ? [...fresh, ...previous] : previous;\n\t\t\t\t});\n\t\t\t} catch (historyError) {\n\t\t\t\t// Left silent in the transcript on purpose: failing to reach further\n\t\t\t\t// back is not a failure of the conversation on screen. Another\n\t\t\t\t// scroll-up retries the same page.\n\t\t\t\tonError?.(\n\t\t\t\t\thistoryError instanceof Error\n\t\t\t\t\t\t? historyError\n\t\t\t\t\t\t: new Error(String(historyError)),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tisLoadingHistoryRef.current = false;\n\t\t\t\tsetIsLoadingHistory(false);\n\t\t\t}\n\t\t})();\n\t}, [applyMessages, hasMoreHistory, onError, readHistoryPage]);\n\n\t// Records pile up one per route per page load otherwise, since every refresh\n\t// writes under a new key.\n\tuseEffect(() => {\n\t\tif (persist) {\n\t\t\tvoid pruneCopilotSessions();\n\t\t}\n\t}, [persist]);\n\n\t// Abort an in-flight turn if the copilot unmounts.\n\tuseEffect(() => () => abortRef.current?.(), []);\n\n\tconst finishStreamingBubble = useCallback(\n\t\t(mutate?: (message: CopilotMessage) => CopilotMessage) => {\n\t\t\tconst streamingId = streamingIdRef.current;\n\t\t\tstreamingIdRef.current = null;\n\t\t\tif (!streamingId) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tapplyMessages((previous) =>\n\t\t\t\tprevious\n\t\t\t\t\t.map((message) => {\n\t\t\t\t\t\tif (message.id !== streamingId) {\n\t\t\t\t\t\t\treturn message;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst settled: CopilotMessage = {\n\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\tisStreaming: false,\n\t\t\t\t\t\t};\n\t\t\t\t\t\treturn mutate ? mutate(settled) : settled;\n\t\t\t\t\t})\n\t\t\t\t\t// An assistant bubble that never received text would render as an\n\t\t\t\t\t// empty balloon; the error banner carries the information instead.\n\t\t\t\t\t// A stopped turn keeps its bubble either way — the interrupted note\n\t\t\t\t\t// is the only trace a turn the reader cut short ever happened.\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(message) =>\n\t\t\t\t\t\t\tmessage.id !== streamingId ||\n\t\t\t\t\t\t\tmessage.content.length > 0 ||\n\t\t\t\t\t\t\tmessage.wasInterrupted === true,\n\t\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\t[applyMessages],\n\t);\n\n\tconst handleEvent = useCallback(\n\t\t(event: CopilotStreamEvent) => {\n\t\t\tconst streamingId = streamingIdRef.current;\n\n\t\t\tif (event.type === 'STREAM') {\n\t\t\t\tconst chunk = readCopilotEventContent(event).text;\n\t\t\t\tif (!streamingId || !chunk) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tapplyMessages((previous) =>\n\t\t\t\t\tprevious.map((message) =>\n\t\t\t\t\t\tmessage.id === streamingId\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\t\t\tcontent: message.content + chunk,\n\t\t\t\t\t\t\t\t\tmessageId: event.messageId ?? message.messageId,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: message,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'TEXT') {\n\t\t\t\t// TEXT carries the whole message, so it replaces the accumulated\n\t\t\t\t// chunks rather than appending — that keeps the bubble correct even if\n\t\t\t\t// a STREAM frame was dropped or duplicated. `responseId` rides inside\n\t\t\t\t// the content payload (as `lastResponseId`).\n\t\t\t\tconst {\n\t\t\t\t\ttext: fullText,\n\t\t\t\t\tfollowUps,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tresponseId,\n\t\t\t\t} = readCopilotEventContent(event);\n\t\t\t\tfinishStreamingBubble((message) => ({\n\t\t\t\t\t...message,\n\t\t\t\t\tcontent: fullText,\n\t\t\t\t\tmessageId: event.messageId ?? message.messageId,\n\t\t\t\t\t...(followUps ? { followUps } : {}),\n\t\t\t\t\t// Kept on the message, not just handled in passing, so the\n\t\t\t\t\t// action button is still there after a reload.\n\t\t\t\t\t...(toolResults ? { toolResults } : {}),\n\t\t\t\t}));\n\t\t\t\tsetThreadResponseId(responseId);\n\t\t\t\tsave();\n\t\t\t\tonResponseComplete?.({\n\t\t\t\t\ttext: fullText,\n\t\t\t\t\tresponseId,\n\t\t\t\t\tfollowUps,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'ERROR') {\n\t\t\t\tsetError(readCopilotEventContent(event).text || GENERIC_ERROR);\n\t\t\t\tfinishStreamingBubble();\n\t\t\t\tsave();\n\t\t\t}\n\n\t\t\t// Unknown types (TOOL_STATUS is declared server side but not emitted)\n\t\t\t// are ignored so a new event type cannot break an existing client.\n\t\t},\n\t\t[\n\t\t\tapplyMessages,\n\t\t\tfinishStreamingBubble,\n\t\t\tonResponseComplete,\n\t\t\tsave,\n\t\t\tsetThreadResponseId,\n\t\t],\n\t);\n\n\tconst sendMessage = useCallback(\n\t\t(message: string) => {\n\t\t\tconst userPrompt = message.trim();\n\t\t\tconst id = sessionIdRef.current;\n\t\t\tif (!userPrompt || !id || isStreaming) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetError(undefined);\n\t\t\tconst now = Date.now();\n\t\t\tconst assistantBubbleId = `copilot-a-${now}`;\n\t\t\tstreamingIdRef.current = assistantBubbleId;\n\n\t\t\tapplyMessages((previous) => [\n\t\t\t\t...previous,\n\t\t\t\t{\n\t\t\t\t\tid: `copilot-u-${now}`,\n\t\t\t\t\trole: 'user',\n\t\t\t\t\tcontent: userPrompt,\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: assistantBubbleId,\n\t\t\t\t\trole: 'assistant',\n\t\t\t\t\tcontent: '',\n\t\t\t\t\ttimestamp: now + 1,\n\t\t\t\t\tisStreaming: true,\n\t\t\t\t},\n\t\t\t]);\n\t\t\tsetIsStreaming(true);\n\t\t\tsave();\n\n\t\t\tabortRef.current = streamCopilotChat(\n\t\t\t\t{\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\tendpointPath,\n\t\t\t\t\theaders,\n\t\t\t\t\tauthToken,\n\t\t\t\t\tgetAuthToken,\n\t\t\t\t\tfetchImpl,\n\t\t\t\t\tstoreId,\n\t\t\t\t\tagent,\n\t\t\t\t\troute,\n\t\t\t\t\tuserPrompt,\n\t\t\t\t\tsessionId: id,\n\t\t\t\t\tpreviousResponseId: previousResponseIdRef.current,\n\t\t\t\t\tsystemPrompt,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonEvent: handleEvent,\n\t\t\t\t\tonComplete: () => {\n\t\t\t\t\t\t// STOP closes the stream without a frame, so this is where a turn\n\t\t\t\t\t\t// ends. TEXT has usually already settled the bubble.\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t},\n\t\t\t\t\tonError: (streamError) => {\n\t\t\t\t\t\tsetError(streamError.message || GENERIC_ERROR);\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t\tonError?.(streamError);\n\t\t\t\t\t},\n\t\t\t\t\tonAbort: () => {\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\t[\n\t\t\tapplyMessages,\n\t\t\tauthToken,\n\t\t\tbaseUrl,\n\t\t\tendpointPath,\n\t\t\tfetchImpl,\n\t\t\tagent,\n\t\t\tfinishStreamingBubble,\n\t\t\tgetAuthToken,\n\t\t\thandleEvent,\n\t\t\theaders,\n\t\t\tisStreaming,\n\t\t\tonError,\n\t\t\troute,\n\t\t\tsave,\n\t\t\tstoreId,\n\t\t\tsystemPrompt,\n\t\t],\n\t);\n\n\tconst regenerate = useCallback(() => {\n\t\tconst hasReply = messagesRef.current.some(\n\t\t\t(message) => message.role === 'assistant' && message.content.length > 0,\n\t\t);\n\t\tif (!hasReply) {\n\t\t\treturn;\n\t\t}\n\t\tsendMessage(COPILOT_REGENERATE_PROMPT);\n\t}, [sendMessage]);\n\n\t/**\n\t * Records a thumbs-up or thumbs-down on one reply.\n\t *\n\t * Fire-and-forget: a rating is a side note to the conversation, so a failed\n\t * post is reported through `onError` and otherwise ignored -- the thumb stays\n\t * lit either way rather than flickering back on a network hiccup.\n\t *\n\t * The reply's own text and the route ride along, so whoever reads the feedback\n\t * sees what was rated without looking the message up.\n\t */\n\tconst submitFeedback = useCallback(\n\t\t(\n\t\t\tmessageId: string,\n\t\t\tfeedback: CopilotFeedbackVote,\n\t\t\tdetail?: CopilotFeedbackDetail,\n\t\t) => {\n\t\t\tconst transport = transportRef.current;\n\t\t\tconst id = sessionIdRef.current;\n\t\t\tif (!id) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// A live turn's bubble carries only a local id until the final event\n\t\t\t// lands, so match on either and let the backend see whichever it gets.\n\t\t\tconst rated = messagesRef.current.find(\n\t\t\t\t(message) => (message.messageId ?? message.id) === messageId,\n\t\t\t);\n\t\t\tvoid sendCopilotFeedback({\n\t\t\t\tbaseUrl: transport.baseUrl,\n\t\t\t\tendpointPath: transport.feedbackPath,\n\t\t\t\theaders: transport.headers,\n\t\t\t\tauthToken: transport.authToken,\n\t\t\t\tgetAuthToken: transport.getAuthToken,\n\t\t\t\tfetchImpl: transport.fetchImpl,\n\t\t\t\tstoreId: transport.storeId,\n\t\t\t\tsessionId: id,\n\t\t\t\tmessageId,\n\t\t\t\tfeedback,\n\t\t\t\troute: routeRef.current,\n\t\t\t\treply: rated?.content,\n\t\t\t\tuser: transport.user,\n\t\t\t\treasons: detail?.reasons,\n\t\t\t\tcomment: detail?.comment,\n\t\t\t}).catch((feedbackError) => {\n\t\t\t\tonError?.(\n\t\t\t\t\tfeedbackError instanceof Error\n\t\t\t\t\t\t? feedbackError\n\t\t\t\t\t\t: new Error(String(feedbackError)),\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\t[onError],\n\t);\n\n\tconst stopStreaming = useCallback(() => {\n\t\tif (!abortRef.current) {\n\t\t\treturn;\n\t\t}\n\t\t// Flagged here rather than in `onAbort`, because an abort that lands between\n\t\t// frames ends the stream through `onComplete` instead. Whichever fires, the\n\t\t// reader stopped this turn, and whatever text had arrived stays.\n\t\tconst streamingId = streamingIdRef.current;\n\t\tif (streamingId) {\n\t\t\tapplyMessages((previous) =>\n\t\t\t\tprevious.map((message) =>\n\t\t\t\t\tmessage.id === streamingId\n\t\t\t\t\t\t? { ...message, wasInterrupted: true }\n\t\t\t\t\t\t: message,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tabortRef.current();\n\t\tabortRef.current = null;\n\t}, [applyMessages]);\n\n\tconst startNewConversation = useCallback(() => {\n\t\tabortRef.current?.();\n\t\tabortRef.current = null;\n\t\tstreamingIdRef.current = null;\n\t\tsetIsStreaming(false);\n\t\tsetError(undefined);\n\t\t// A new conversation has no history behind it; the old session's pages\n\t\t// belong to the old session id.\n\t\tnextHistoryPageRef.current = 1;\n\t\tisLoadingHistoryRef.current = false;\n\t\tsetIsLoadingHistory(false);\n\t\tsetHasMoreHistory(false);\n\n\t\tconst activeRoute = routeRef.current;\n\t\t// The conversation being cleared, so its stored transcript can go with it.\n\t\tconst clearedId = sessionIdRef.current;\n\t\t// A host-pinned id is the host's to change, so only clear its transcript.\n\t\tconst nextId =\n\t\t\tpinnedSessionId ??\n\t\t\tresetCopilotSessionForRoute({ route: activeRoute, storeId });\n\t\tsessionIdRef.current = nextId;\n\t\tsetSessionId(nextId);\n\t\tmessagesRef.current = [];\n\t\tsetMessages([]);\n\t\tsetThreadResponseId(undefined);\n\n\t\t// \"Refresh chat\" wipes the record, not just the screen: the cleared\n\t\t// conversation is deleted from IndexedDB so reopening the tab starts fresh\n\t\t// instead of resuming it. Nothing is written for the new session here — its\n\t\t// first record is stamped when the first turn is sent, which is also what\n\t\t// keeps an untouched refresh from leaving an empty record behind.\n\t\tif (persist && clearedId) {\n\t\t\tvoid deleteCopilotSession(activeRoute, clearedId);\n\t\t}\n\t\tonSessionIdChange?.(nextId);\n\t}, [\n\t\tonSessionIdChange,\n\t\tpersist,\n\t\tpinnedSessionId,\n\t\tsetThreadResponseId,\n\t\tstoreId,\n\t]);\n\n\t// The thinking bubble is only for the wait before the first token; once text\n\t// starts arriving the bubble itself shows progress.\n\tconst isThinking = useMemo(\n\t\t() =>\n\t\t\tisStreaming &&\n\t\t\t!messages.some((message) => message.isStreaming && message.content),\n\t\t[isStreaming, messages],\n\t);\n\n\treturn {\n\t\tmessages,\n\t\tsessionId,\n\t\tpreviousResponseId,\n\t\tisStreaming,\n\t\tisThinking,\n\t\tisRestoring,\n\t\tisLoadingHistory,\n\t\thasMoreHistory,\n\t\terror,\n\t\tsendMessage,\n\t\tregenerate,\n\t\tsubmitFeedback,\n\t\tloadOlderMessages,\n\t\tstopStreaming,\n\t\tstartNewConversation,\n\t};\n};\n"],"names":["GENERIC_ERROR","asRestored","messages","message","useCopilotStreamChat","storeId","agent","DEFAULT_COPILOT_AGENT","route","DEFAULT_COPILOT_ROUTE","messagesPath","feedbackPath","user","loadHistory","systemPrompt","pinnedSessionId","persist","onError","onResponseComplete","onSessionIdChange","baseUrl","endpointPath","headers","authToken","getAuthToken","fetchImpl","setMessages","useState","sessionId","setSessionId","isStreaming","setIsStreaming","isRestoring","setIsRestoring","error","setError","previousResponseId","setPreviousResponseId","isLoadingHistory","setIsLoadingHistory","hasMoreHistory","setHasMoreHistory","messagesRef","useRef","previousResponseIdRef","streamingIdRef","abortRef","sessionIdRef","routeRef","nextHistoryPageRef","isLoadingHistoryRef","applyMessages","useCallback","updater","next","setThreadResponseId","responseId","save","id","persistCopilotTurn","transportRef","readHistoryPage","page","transport","historyPage","fetchCopilotMessages","COPILOT_HISTORY_PAGE_SIZE","useEffect","cancelled","resolveCopilotSessionIdForRoute","getCopilotSessionIdForRoute","record","loadCopilotSession","firstPage","loadOlderMessages","older","previous","known","fresh","historyError","pruneCopilotSessions","finishStreamingBubble","mutate","streamingId","settled","handleEvent","event","chunk","readCopilotEventContent","fullText","followUps","toolResults","sendMessage","userPrompt","now","assistantBubbleId","streamCopilotChat","streamError","regenerate","COPILOT_REGENERATE_PROMPT","submitFeedback","messageId","feedback","detail","rated","sendCopilotFeedback","feedbackError","stopStreaming","startNewConversation","activeRoute","clearedId","nextId","resetCopilotSessionForRoute","deleteCopilotSession","isThinking","useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"useCopilotStreamChat.js","sources":["../../../../src/components/bik-copilot/useCopilotStreamChat.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { COPILOT_REGENERATE_PROMPT } from './copilotRegenerate';\nimport {\n\tCopilotFeedbackDetail,\n\tCopilotFeedbackVote,\n\tCopilotMessage,\n\tCopilotStreamEvent,\n\tUseCopilotStreamChatOptions,\n\tUseCopilotStreamChatResult,\n} from './model';\nimport {\n\tdeleteCopilotSession,\n\tloadCopilotSession,\n\tpersistCopilotTurn,\n\tpruneCopilotSessions,\n} from './services/copilotDb';\nimport { sendCopilotFeedback } from './services/copilotFeedbackClient';\nimport {\n\tCOPILOT_HISTORY_PAGE_SIZE,\n\tfetchCopilotMessages,\n} from './services/copilotMessagesClient';\nimport {\n\tgetCopilotSessionId,\n\tresetCopilotSession,\n\tresolveCopilotSessionId,\n} from './services/copilotPageSession';\nimport {\n\treadCopilotEventContent,\n\tstreamCopilotChat,\n} from './services/copilotStreamClient';\nimport {\n\tDEFAULT_COPILOT_AGENT,\n\tDEFAULT_COPILOT_ROUTE,\n} from './useCopilotIcebreakers';\n\nconst GENERIC_ERROR = 'Something went wrong. Please try again.';\n\n/**\n * Runs a merchant copilot conversation against the streaming\n * `/bik-ai/copilot-chatbot` endpoint.\n *\n * Owns three things the endpoint's contract requires:\n *\n * 1. **The session id.** One per store, not per route: the merchant moving\n * between dashboard pages stays in the same conversation, and so does a\n * refresh — the ids live in memory but are recovered from the stored records,\n * which is what keeps them lined up with the history the backend keys by them\n * (see `copilotPageSession`). The route travels with each turn instead, so the\n * backend still loads the POD, Area and page knowledge of wherever the\n * merchant is now.\n * 2. **`previousResponseId`.** Absent on the first turn; from then on it is the\n * `responseId` of the last `TEXT` event, which is what makes OpenAI replay the\n * earlier turns server side. A turn that breaks halfway returns no\n * `responseId`, and the backend means that — the next turn starts fresh.\n * 3. **The transcript**, stored in IndexedDB under the session id and written\n * every turn, so leaving the page mid-conversation loses nothing.\n */\nconst asRestored = (messages: CopilotMessage[]): CopilotMessage[] =>\n\tmessages.map((message) =>\n\t\tmessage.role === 'assistant' ? { ...message, isRestored: true } : message,\n\t);\n\nexport const useCopilotStreamChat = ({\n\tstoreId,\n\tagent = DEFAULT_COPILOT_AGENT,\n\troute = DEFAULT_COPILOT_ROUTE,\n\tmessagesPath,\n\tfeedbackPath,\n\tuser,\n\tloadHistory = true,\n\tsystemPrompt,\n\tsessionId: pinnedSessionId,\n\tpersist = true,\n\tonError,\n\tonResponseComplete,\n\tonSessionIdChange,\n\tbaseUrl,\n\tendpointPath,\n\theaders,\n\tauthToken,\n\tgetAuthToken,\n\tfetchImpl,\n}: UseCopilotStreamChatOptions): UseCopilotStreamChatResult => {\n\tconst [messages, setMessages] = useState<CopilotMessage[]>([]);\n\tconst [sessionId, setSessionId] = useState<string | null>(\n\t\tpinnedSessionId ?? null,\n\t);\n\tconst [isStreaming, setIsStreaming] = useState(false);\n\tconst [isRestoring, setIsRestoring] = useState(true);\n\tconst [error, setError] = useState<string | undefined>();\n\tconst [previousResponseId, setPreviousResponseId] = useState<\n\t\tstring | undefined\n\t>();\n\tconst [isLoadingHistory, setIsLoadingHistory] = useState(false);\n\tconst [hasMoreHistory, setHasMoreHistory] = useState(false);\n\n\t// Async stream handlers run long after the render that created them, so the\n\t// live values live in refs and state is only the render mirror.\n\tconst messagesRef = useRef<CopilotMessage[]>([]);\n\tconst previousResponseIdRef = useRef<string | undefined>(undefined);\n\tconst streamingIdRef = useRef<string | null>(null);\n\tconst abortRef = useRef<(() => void) | null>(null);\n\tconst sessionIdRef = useRef<string | null>(pinnedSessionId ?? null);\n\t// The active route, for the async handlers that write the transcript.\n\tconst routeRef = useRef<string>(route);\n\trouteRef.current = route;\n\t// Next page of stored history to ask for. Starts at 2 when the local cache\n\t// already holds page 1's worth, which is the steady state.\n\tconst nextHistoryPageRef = useRef(1);\n\tconst isLoadingHistoryRef = useRef(false);\n\n\tconst applyMessages = useCallback(\n\t\t(updater: (previous: CopilotMessage[]) => CopilotMessage[]) => {\n\t\t\tconst next = updater(messagesRef.current);\n\t\t\tmessagesRef.current = next;\n\t\t\tsetMessages(next);\n\t\t},\n\t\t[],\n\t);\n\n\tconst setThreadResponseId = useCallback((responseId: string | undefined) => {\n\t\tpreviousResponseIdRef.current = responseId;\n\t\tsetPreviousResponseId(responseId);\n\t}, []);\n\n\tconst save = useCallback(() => {\n\t\tconst id = sessionIdRef.current;\n\t\tif (!persist || !id) {\n\t\t\treturn;\n\t\t}\n\t\tvoid persistCopilotTurn({\n\t\t\troute: routeRef.current,\n\t\t\tsessionId: id,\n\t\t\tmessages: messagesRef.current,\n\t\t\tpreviousResponseId: previousResponseIdRef.current,\n\t\t\tstoreId,\n\t\t\tagent,\n\t\t});\n\t}, [agent, persist, storeId]);\n\n\t// Transport config for the async readers below. Held in a ref rather than in\n\t// the effect's deps: a host that passes an inline `headers` object would\n\t// otherwise re-run restore on every render and wipe the transcript.\n\tconst transportRef = useRef({\n\t\tbaseUrl,\n\t\tmessagesPath,\n\t\tfeedbackPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tloadHistory,\n\t\tuser,\n\t});\n\ttransportRef.current = {\n\t\tbaseUrl,\n\t\tmessagesPath,\n\t\tfeedbackPath,\n\t\theaders,\n\t\tauthToken,\n\t\tgetAuthToken,\n\t\tfetchImpl,\n\t\tstoreId,\n\t\tloadHistory,\n\t\tuser,\n\t};\n\n\tconst readHistoryPage = useCallback(async (page: number) => {\n\t\tconst transport = transportRef.current;\n\t\tconst id = sessionIdRef.current;\n\t\tif (!transport.loadHistory || !id) {\n\t\t\treturn null;\n\t\t}\n\t\tconst historyPage = await fetchCopilotMessages({\n\t\t\tbaseUrl: transport.baseUrl,\n\t\t\tendpointPath: transport.messagesPath,\n\t\t\theaders: transport.headers,\n\t\t\tauthToken: transport.authToken,\n\t\t\tgetAuthToken: transport.getAuthToken,\n\t\t\tfetchImpl: transport.fetchImpl,\n\t\t\tstoreId: transport.storeId,\n\t\t\tsessionId: id,\n\t\t\tpage,\n\t\t\tpageSize: COPILOT_HISTORY_PAGE_SIZE,\n\t\t});\n\t\treturn { ...historyPage, messages: asRestored(historyPage.messages) };\n\t}, []);\n\n\t// Resolve the store's conversation and read it back from IndexedDB.\n\t//\n\t// Deliberately not keyed on `route`: navigating is not a new chat, so a route\n\t// change must not restore, reset the transcript or abort a turn that is still\n\t// streaming. `routeRef` carries the current page into the next turn instead.\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tconst restore = async () => {\n\t\t\tabortRef.current?.();\n\t\t\tabortRef.current = null;\n\t\t\tstreamingIdRef.current = null;\n\t\t\tsetIsStreaming(false);\n\t\t\tsetError(undefined);\n\t\t\tsetIsRestoring(true);\n\t\t\tsetHasMoreHistory(false);\n\t\t\tisLoadingHistoryRef.current = false;\n\t\t\tsetIsLoadingHistory(false);\n\n\t\t\tconst id =\n\t\t\t\tpinnedSessionId ??\n\t\t\t\t(persist\n\t\t\t\t\t? await resolveCopilotSessionId({ storeId })\n\t\t\t\t\t: getCopilotSessionId({ storeId }));\n\t\t\tconst record = persist ? await loadCopilotSession(id) : null;\n\t\t\tif (cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsessionIdRef.current = id;\n\t\t\tsetSessionId(id);\n\t\t\tmessagesRef.current = asRestored(record?.messages ?? []);\n\t\t\tsetMessages(messagesRef.current);\n\t\t\tsetThreadResponseId(record?.previousResponseId);\n\t\t\tsetIsRestoring(false);\n\t\t\tonSessionIdChange?.(id);\n\n\t\t\t// The cache holds at most one page, so what is on screen already *is*\n\t\t\t// page 1 and the reader's first scroll-up wants page 2.\n\t\t\tif (messagesRef.current.length > 0) {\n\t\t\t\tnextHistoryPageRef.current = 2;\n\t\t\t\tsetHasMoreHistory(transportRef.current.loadHistory);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Nothing cached and nothing to scroll, so page 1 has to be fetched for\n\t\t\t// the history to be reachable at all — but only for an id the host\n\t\t\t// pinned. An id this library resolved came out of the local records, so\n\t\t\t// an empty cache for it means an empty conversation, and a freshly\n\t\t\t// minted one has nothing behind it by definition. Asking anyway would\n\t\t\t// put a pointless request on the start of every new conversation.\n\t\t\tif (!pinnedSessionId) {\n\t\t\t\tnextHistoryPageRef.current = 1;\n\t\t\t\tsetHasMoreHistory(false);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tnextHistoryPageRef.current = 1;\n\t\t\ttry {\n\t\t\t\tconst firstPage = await readHistoryPage(1);\n\t\t\t\tif (cancelled || !firstPage) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnextHistoryPageRef.current = 2;\n\t\t\t\tapplyMessages(() => firstPage.messages);\n\t\t\t\tsetHasMoreHistory(firstPage.hasMore);\n\t\t\t} catch {\n\t\t\t\t// A session the backend has never heard of is the normal case for a\n\t\t\t\t// host-pinned id on its first use; the empty state covers it.\n\t\t\t\tsetHasMoreHistory(false);\n\t\t\t}\n\t\t};\n\n\t\tvoid restore();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t\t// onSessionIdChange is event-like: re-running restore because the host\n\t\t// passed a new inline callback would wipe the transcript.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [\n\t\tstoreId,\n\t\tpinnedSessionId,\n\t\tpersist,\n\t\tsetThreadResponseId,\n\t\tapplyMessages,\n\t\treadHistoryPage,\n\t]);\n\n\t/**\n\t * Prepends the page before the oldest message on screen.\n\t *\n\t * Guarded by a ref rather than the state flag because a scroll handler can\n\t * fire many times before React re-renders, and each of those would otherwise\n\t * start its own request for the same page.\n\t */\n\tconst loadOlderMessages = useCallback(() => {\n\t\tif (isLoadingHistoryRef.current || !hasMoreHistory) {\n\t\t\treturn;\n\t\t}\n\t\tisLoadingHistoryRef.current = true;\n\t\tsetIsLoadingHistory(true);\n\n\t\tconst page = nextHistoryPageRef.current;\n\t\tvoid (async () => {\n\t\t\ttry {\n\t\t\t\tconst older = await readHistoryPage(page);\n\t\t\t\tif (!older) {\n\t\t\t\t\tsetHasMoreHistory(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnextHistoryPageRef.current = page + 1;\n\t\t\t\tsetHasMoreHistory(older.hasMore);\n\t\t\t\tapplyMessages((previous) => {\n\t\t\t\t\tconst known = new Set(\n\t\t\t\t\t\tprevious.flatMap((message) =>\n\t\t\t\t\t\t\tmessage.messageId\n\t\t\t\t\t\t\t\t? [message.id, message.messageId]\n\t\t\t\t\t\t\t\t: [message.id],\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\tconst fresh = older.messages.filter(\n\t\t\t\t\t\t(message) => !known.has(message.id),\n\t\t\t\t\t);\n\t\t\t\t\treturn fresh.length > 0 ? [...fresh, ...previous] : previous;\n\t\t\t\t});\n\t\t\t} catch (historyError) {\n\t\t\t\t// Left silent in the transcript on purpose: failing to reach further\n\t\t\t\t// back is not a failure of the conversation on screen. Another\n\t\t\t\t// scroll-up retries the same page.\n\t\t\t\tonError?.(\n\t\t\t\t\thistoryError instanceof Error\n\t\t\t\t\t\t? historyError\n\t\t\t\t\t\t: new Error(String(historyError)),\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tisLoadingHistoryRef.current = false;\n\t\t\t\tsetIsLoadingHistory(false);\n\t\t\t}\n\t\t})();\n\t}, [applyMessages, hasMoreHistory, onError, readHistoryPage]);\n\n\t// Records pile up one per route per page load otherwise, since every refresh\n\t// writes under a new key.\n\tuseEffect(() => {\n\t\tif (persist) {\n\t\t\tvoid pruneCopilotSessions();\n\t\t}\n\t}, [persist]);\n\n\t// Abort an in-flight turn if the copilot unmounts.\n\tuseEffect(() => () => abortRef.current?.(), []);\n\n\tconst finishStreamingBubble = useCallback(\n\t\t(mutate?: (message: CopilotMessage) => CopilotMessage) => {\n\t\t\tconst streamingId = streamingIdRef.current;\n\t\t\tstreamingIdRef.current = null;\n\t\t\tif (!streamingId) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tapplyMessages((previous) =>\n\t\t\t\tprevious\n\t\t\t\t\t.map((message) => {\n\t\t\t\t\t\tif (message.id !== streamingId) {\n\t\t\t\t\t\t\treturn message;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst settled: CopilotMessage = {\n\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\tisStreaming: false,\n\t\t\t\t\t\t};\n\t\t\t\t\t\treturn mutate ? mutate(settled) : settled;\n\t\t\t\t\t})\n\t\t\t\t\t// An assistant bubble that never received text would render as an\n\t\t\t\t\t// empty balloon; the error banner carries the information instead.\n\t\t\t\t\t// A stopped turn keeps its bubble either way — the interrupted note\n\t\t\t\t\t// is the only trace a turn the reader cut short ever happened.\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(message) =>\n\t\t\t\t\t\t\tmessage.id !== streamingId ||\n\t\t\t\t\t\t\tmessage.content.length > 0 ||\n\t\t\t\t\t\t\tmessage.wasInterrupted === true,\n\t\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\t[applyMessages],\n\t);\n\n\tconst handleEvent = useCallback(\n\t\t(event: CopilotStreamEvent) => {\n\t\t\tconst streamingId = streamingIdRef.current;\n\n\t\t\tif (event.type === 'STREAM') {\n\t\t\t\tconst chunk = readCopilotEventContent(event).text;\n\t\t\t\tif (!streamingId || !chunk) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tapplyMessages((previous) =>\n\t\t\t\t\tprevious.map((message) =>\n\t\t\t\t\t\tmessage.id === streamingId\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\t\t\tcontent: message.content + chunk,\n\t\t\t\t\t\t\t\t\tmessageId: event.messageId ?? message.messageId,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: message,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'TEXT') {\n\t\t\t\t// TEXT carries the whole message, so it replaces the accumulated\n\t\t\t\t// chunks rather than appending — that keeps the bubble correct even if\n\t\t\t\t// a STREAM frame was dropped or duplicated. `responseId` rides inside\n\t\t\t\t// the content payload (as `lastResponseId`).\n\t\t\t\tconst {\n\t\t\t\t\ttext: fullText,\n\t\t\t\t\tfollowUps,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tresponseId,\n\t\t\t\t} = readCopilotEventContent(event);\n\t\t\t\tfinishStreamingBubble((message) => ({\n\t\t\t\t\t...message,\n\t\t\t\t\tcontent: fullText,\n\t\t\t\t\tmessageId: event.messageId ?? message.messageId,\n\t\t\t\t\t...(followUps ? { followUps } : {}),\n\t\t\t\t\t// Kept on the message, not just handled in passing, so the\n\t\t\t\t\t// action button is still there after a reload.\n\t\t\t\t\t...(toolResults ? { toolResults } : {}),\n\t\t\t\t}));\n\t\t\t\tsetThreadResponseId(responseId);\n\t\t\t\tsave();\n\t\t\t\tonResponseComplete?.({\n\t\t\t\t\ttext: fullText,\n\t\t\t\t\tresponseId,\n\t\t\t\t\tfollowUps,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.type === 'ERROR') {\n\t\t\t\tsetError(readCopilotEventContent(event).text || GENERIC_ERROR);\n\t\t\t\tfinishStreamingBubble();\n\t\t\t\tsave();\n\t\t\t}\n\n\t\t\t// Unknown types (TOOL_STATUS is declared server side but not emitted)\n\t\t\t// are ignored so a new event type cannot break an existing client.\n\t\t},\n\t\t[\n\t\t\tapplyMessages,\n\t\t\tfinishStreamingBubble,\n\t\t\tonResponseComplete,\n\t\t\tsave,\n\t\t\tsetThreadResponseId,\n\t\t],\n\t);\n\n\tconst sendMessage = useCallback(\n\t\t(message: string) => {\n\t\t\tconst userPrompt = message.trim();\n\t\t\tconst id = sessionIdRef.current;\n\t\t\tif (!userPrompt || !id || isStreaming) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetError(undefined);\n\t\t\tconst now = Date.now();\n\t\t\tconst assistantBubbleId = `copilot-a-${now}`;\n\t\t\tstreamingIdRef.current = assistantBubbleId;\n\n\t\t\tapplyMessages((previous) => [\n\t\t\t\t...previous,\n\t\t\t\t{\n\t\t\t\t\tid: `copilot-u-${now}`,\n\t\t\t\t\trole: 'user',\n\t\t\t\t\tcontent: userPrompt,\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: assistantBubbleId,\n\t\t\t\t\trole: 'assistant',\n\t\t\t\t\tcontent: '',\n\t\t\t\t\ttimestamp: now + 1,\n\t\t\t\t\tisStreaming: true,\n\t\t\t\t},\n\t\t\t]);\n\t\t\tsetIsStreaming(true);\n\t\t\tsave();\n\n\t\t\tabortRef.current = streamCopilotChat(\n\t\t\t\t{\n\t\t\t\t\tbaseUrl,\n\t\t\t\t\tendpointPath,\n\t\t\t\t\theaders,\n\t\t\t\t\tauthToken,\n\t\t\t\t\tgetAuthToken,\n\t\t\t\t\tfetchImpl,\n\t\t\t\t\tstoreId,\n\t\t\t\t\tagent,\n\t\t\t\t\troute,\n\t\t\t\t\tuserPrompt,\n\t\t\t\t\tsessionId: id,\n\t\t\t\t\tpreviousResponseId: previousResponseIdRef.current,\n\t\t\t\t\tsystemPrompt,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonEvent: handleEvent,\n\t\t\t\t\tonComplete: () => {\n\t\t\t\t\t\t// STOP closes the stream without a frame, so this is where a turn\n\t\t\t\t\t\t// ends. TEXT has usually already settled the bubble.\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t},\n\t\t\t\t\tonError: (streamError) => {\n\t\t\t\t\t\tsetError(streamError.message || GENERIC_ERROR);\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t\tonError?.(streamError);\n\t\t\t\t\t},\n\t\t\t\t\tonAbort: () => {\n\t\t\t\t\t\tfinishStreamingBubble();\n\t\t\t\t\t\tsetIsStreaming(false);\n\t\t\t\t\t\tabortRef.current = null;\n\t\t\t\t\t\tsave();\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\t[\n\t\t\tapplyMessages,\n\t\t\tauthToken,\n\t\t\tbaseUrl,\n\t\t\tendpointPath,\n\t\t\tfetchImpl,\n\t\t\tagent,\n\t\t\tfinishStreamingBubble,\n\t\t\tgetAuthToken,\n\t\t\thandleEvent,\n\t\t\theaders,\n\t\t\tisStreaming,\n\t\t\tonError,\n\t\t\troute,\n\t\t\tsave,\n\t\t\tstoreId,\n\t\t\tsystemPrompt,\n\t\t],\n\t);\n\n\tconst regenerate = useCallback(() => {\n\t\tconst hasReply = messagesRef.current.some(\n\t\t\t(message) => message.role === 'assistant' && message.content.length > 0,\n\t\t);\n\t\tif (!hasReply) {\n\t\t\treturn;\n\t\t}\n\t\tsendMessage(COPILOT_REGENERATE_PROMPT);\n\t}, [sendMessage]);\n\n\t/**\n\t * Records a thumbs-up or thumbs-down on one reply.\n\t *\n\t * Fire-and-forget: a rating is a side note to the conversation, so a failed\n\t * post is reported through `onError` and otherwise ignored -- the thumb stays\n\t * lit either way rather than flickering back on a network hiccup.\n\t *\n\t * The reply's own text and the route ride along, so whoever reads the feedback\n\t * sees what was rated without looking the message up.\n\t */\n\tconst submitFeedback = useCallback(\n\t\t(\n\t\t\tmessageId: string,\n\t\t\tfeedback: CopilotFeedbackVote,\n\t\t\tdetail?: CopilotFeedbackDetail,\n\t\t) => {\n\t\t\tconst transport = transportRef.current;\n\t\t\tconst id = sessionIdRef.current;\n\t\t\tif (!id) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// A live turn's bubble carries only a local id until the final event\n\t\t\t// lands, so match on either and let the backend see whichever it gets.\n\t\t\tconst rated = messagesRef.current.find(\n\t\t\t\t(message) => (message.messageId ?? message.id) === messageId,\n\t\t\t);\n\t\t\tvoid sendCopilotFeedback({\n\t\t\t\tbaseUrl: transport.baseUrl,\n\t\t\t\tendpointPath: transport.feedbackPath,\n\t\t\t\theaders: transport.headers,\n\t\t\t\tauthToken: transport.authToken,\n\t\t\t\tgetAuthToken: transport.getAuthToken,\n\t\t\t\tfetchImpl: transport.fetchImpl,\n\t\t\t\tstoreId: transport.storeId,\n\t\t\t\tsessionId: id,\n\t\t\t\tmessageId,\n\t\t\t\tfeedback,\n\t\t\t\troute: routeRef.current,\n\t\t\t\treply: rated?.content,\n\t\t\t\tuser: transport.user,\n\t\t\t\treasons: detail?.reasons,\n\t\t\t\tcomment: detail?.comment,\n\t\t\t}).catch((feedbackError) => {\n\t\t\t\tonError?.(\n\t\t\t\t\tfeedbackError instanceof Error\n\t\t\t\t\t\t? feedbackError\n\t\t\t\t\t\t: new Error(String(feedbackError)),\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\t[onError],\n\t);\n\n\tconst stopStreaming = useCallback(() => {\n\t\tif (!abortRef.current) {\n\t\t\treturn;\n\t\t}\n\t\t// Flagged here rather than in `onAbort`, because an abort that lands between\n\t\t// frames ends the stream through `onComplete` instead. Whichever fires, the\n\t\t// reader stopped this turn, and whatever text had arrived stays.\n\t\tconst streamingId = streamingIdRef.current;\n\t\tif (streamingId) {\n\t\t\tapplyMessages((previous) =>\n\t\t\t\tprevious.map((message) =>\n\t\t\t\t\tmessage.id === streamingId\n\t\t\t\t\t\t? { ...message, wasInterrupted: true }\n\t\t\t\t\t\t: message,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tabortRef.current();\n\t\tabortRef.current = null;\n\t}, [applyMessages]);\n\n\tconst startNewConversation = useCallback(() => {\n\t\tabortRef.current?.();\n\t\tabortRef.current = null;\n\t\tstreamingIdRef.current = null;\n\t\tsetIsStreaming(false);\n\t\tsetError(undefined);\n\t\t// A new conversation has no history behind it; the old session's pages\n\t\t// belong to the old session id.\n\t\tnextHistoryPageRef.current = 1;\n\t\tisLoadingHistoryRef.current = false;\n\t\tsetIsLoadingHistory(false);\n\t\tsetHasMoreHistory(false);\n\n\t\t// The conversation being cleared, so its stored transcript can go with it.\n\t\tconst clearedId = sessionIdRef.current;\n\t\t// A host-pinned id is the host's to change, so only clear its transcript.\n\t\tconst nextId = pinnedSessionId ?? resetCopilotSession({ storeId });\n\t\tsessionIdRef.current = nextId;\n\t\tsetSessionId(nextId);\n\t\tmessagesRef.current = [];\n\t\tsetMessages([]);\n\t\tsetThreadResponseId(undefined);\n\n\t\t// \"Refresh chat\" wipes the record, not just the screen: the cleared\n\t\t// conversation is deleted from IndexedDB so reopening the tab starts fresh\n\t\t// instead of resuming it. Nothing is written for the new session here — its\n\t\t// first record is stamped when the first turn is sent, which is also what\n\t\t// keeps an untouched refresh from leaving an empty record behind.\n\t\tif (persist && clearedId) {\n\t\t\tvoid deleteCopilotSession(clearedId);\n\t\t}\n\t\tonSessionIdChange?.(nextId);\n\t}, [\n\t\tonSessionIdChange,\n\t\tpersist,\n\t\tpinnedSessionId,\n\t\tsetThreadResponseId,\n\t\tstoreId,\n\t]);\n\n\t// The thinking bubble is only for the wait before the first token; once text\n\t// starts arriving the bubble itself shows progress.\n\tconst isThinking = useMemo(\n\t\t() =>\n\t\t\tisStreaming &&\n\t\t\t!messages.some((message) => message.isStreaming && message.content),\n\t\t[isStreaming, messages],\n\t);\n\n\treturn {\n\t\tmessages,\n\t\tsessionId,\n\t\tpreviousResponseId,\n\t\tisStreaming,\n\t\tisThinking,\n\t\tisRestoring,\n\t\tisLoadingHistory,\n\t\thasMoreHistory,\n\t\terror,\n\t\tsendMessage,\n\t\tregenerate,\n\t\tsubmitFeedback,\n\t\tloadOlderMessages,\n\t\tstopStreaming,\n\t\tstartNewConversation,\n\t};\n};\n"],"names":["GENERIC_ERROR","asRestored","messages","message","useCopilotStreamChat","storeId","agent","DEFAULT_COPILOT_AGENT","route","DEFAULT_COPILOT_ROUTE","messagesPath","feedbackPath","user","loadHistory","systemPrompt","pinnedSessionId","persist","onError","onResponseComplete","onSessionIdChange","baseUrl","endpointPath","headers","authToken","getAuthToken","fetchImpl","setMessages","useState","sessionId","setSessionId","isStreaming","setIsStreaming","isRestoring","setIsRestoring","error","setError","previousResponseId","setPreviousResponseId","isLoadingHistory","setIsLoadingHistory","hasMoreHistory","setHasMoreHistory","messagesRef","useRef","previousResponseIdRef","streamingIdRef","abortRef","sessionIdRef","routeRef","nextHistoryPageRef","isLoadingHistoryRef","applyMessages","useCallback","updater","next","setThreadResponseId","responseId","save","id","persistCopilotTurn","transportRef","readHistoryPage","page","transport","historyPage","fetchCopilotMessages","COPILOT_HISTORY_PAGE_SIZE","useEffect","cancelled","resolveCopilotSessionId","getCopilotSessionId","record","loadCopilotSession","firstPage","loadOlderMessages","older","previous","known","fresh","historyError","pruneCopilotSessions","finishStreamingBubble","mutate","streamingId","settled","handleEvent","event","chunk","readCopilotEventContent","fullText","followUps","toolResults","sendMessage","userPrompt","now","assistantBubbleId","streamCopilotChat","streamError","regenerate","COPILOT_REGENERATE_PROMPT","submitFeedback","messageId","feedback","detail","rated","sendCopilotFeedback","feedbackError","stopStreaming","startNewConversation","clearedId","nextId","resetCopilotSession","deleteCopilotSession","isThinking","useMemo"],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -2,7 +2,7 @@ import * as o from "./components/template-preview/constants/regexPatterns.js";
2
2
  import { default as t } from "./utils/StringUtils.js";
3
3
  import { BASE_COLORS as p, COLORS as f, DEFAULT_THEME as m, FONTS as l } from "./constants/Theme.js";
4
4
  import { ComponentZindex as n } from "./constants/zindex.js";
5
- import { AiBodyCaption as s, AiBodyTiny as d, BodyCaption as u, BodyLarge as T, BodyPrimary as C, BodyPrimaryLink as A, BodyRegular as S, BodySecondary as c, BodySecondaryLink as E, BodySmall as I, BodyTiny as P, BodyTinySemiBold as _, ButtonLarge as R, ButtonLargeAI as O, ButtonRegular as h, ButtonRegularAI as g, Caption as N, CaptionBold as L, Display as B, SmallRegular as D, SubHeading as M, TextPlaceholder as y, Tiny as k, TitleFour as F, TitleLarge as U, TitleMedium as b, TitleRegular as H, TitleSmall as w, TitleTiny as G, TitleXlarge as V } from "./components/TypographyStyle.js";
5
+ import { AiBodyCaption as s, AiBodyTiny as d, BodyCaption as u, BodyLarge as T, BodyPrimary as C, BodyPrimaryLink as A, BodyRegular as S, BodySecondary as c, BodySecondaryLink as E, BodySmall as I, BodyTiny as P, BodyTinySemiBold as _, ButtonLarge as O, ButtonLargeAI as R, ButtonRegular as h, ButtonRegularAI as g, Caption as N, CaptionBold as L, Display as B, SmallRegular as D, SubHeading as M, TextPlaceholder as y, Tiny as k, TitleFour as F, TitleLarge as U, TitleMedium as b, TitleRegular as H, TitleSmall as w, TitleTiny as G, TitleXlarge as V } from "./components/TypographyStyle.js";
6
6
  import { SearchFilter as W } from "./components/SearchFilter/index.js";
7
7
  import { ResizableImage as K } from "./components/resizeImage/index.js";
8
8
  import { validateURL as X } from "./utils/validator.js";
@@ -20,7 +20,7 @@ import { default as Ao } from "./assets/icons/alarm.svg.js";
20
20
  import { default as co } from "./assets/icons/alert.svg.js";
21
21
  import { default as Io } from "./assets/icons/alert_triangle.svg.js";
22
22
  import { default as _o } from "./assets/icons/arrow_back.svg.js";
23
- import { default as Oo } from "./assets/icons/arrow_down.svg.js";
23
+ import { default as Ro } from "./assets/icons/arrow_down.svg.js";
24
24
  import { default as go } from "./assets/icons/arrow_left.svg.js";
25
25
  import { default as Lo } from "./assets/icons/arrow_up.svg.js";
26
26
  import { default as Do } from "./assets/icons/back_icon.svg.js";
@@ -47,7 +47,7 @@ import { default as Ar } from "./assets/icons/checklistIcon.svg.js";
47
47
  import { default as cr } from "./assets/icons/chevronDown.svg.js";
48
48
  import { default as Ir } from "./assets/icons/chevronDownOutline.svg.js";
49
49
  import { default as _r } from "./assets/icons/chevronLeft.svg.js";
50
- import { default as Or } from "./assets/icons/chevronLeft2.svg.js";
50
+ import { default as Rr } from "./assets/icons/chevronLeft2.svg.js";
51
51
  import { default as gr } from "./assets/icons/chevronRight.svg.js";
52
52
  import { default as Lr } from "./assets/icons/chevronRight2.svg.js";
53
53
  import { default as Dr } from "./assets/icons/chevronRightAlt.svg.js";
@@ -74,7 +74,7 @@ import { default as Ae } from "./assets/icons/emoji.svg.js";
74
74
  import { default as ce } from "./assets/icons/EnableIcon.js";
75
75
  import { default as Ie } from "./assets/icons/errorIcon.svg.js";
76
76
  import { default as _e } from "./assets/icons/errorInfo.svg.js";
77
- import { default as Oe } from "./assets/icons/expressionless_emoji.svg.js";
77
+ import { default as Re } from "./assets/icons/expressionless_emoji.svg.js";
78
78
  import { default as ge } from "./assets/icons/facebook_channel.svg.js";
79
79
  import { default as Le } from "./components/feature-announcements/FeatureAnnouncementProvider.js";
80
80
  import { default as De } from "./assets/icons/file.svg.js";
@@ -101,7 +101,7 @@ import { default as At } from "./assets/icons/italic.svg.js";
101
101
  import { default as ct } from "./assets/icons/list.svg.js";
102
102
  import { default as It } from "./assets/icons/ListChecksIcon.js";
103
103
  import { default as _t } from "./assets/icons/locked.svg.js";
104
- import { default as Ot } from "./assets/icons/log_out.svg.js";
104
+ import { default as Rt } from "./assets/icons/log_out.svg.js";
105
105
  import { default as gt } from "./assets/icons/lto_icon.svg.js";
106
106
  import { default as Lt } from "./components/feature-announcements/MajorUpdatePopup.js";
107
107
  import { default as Dt } from "./components/markdown/MarkdownRender.js";
@@ -128,7 +128,7 @@ import { default as Aa } from "./components/ProgressChecklist/ProgressChecklist.
128
128
  import { default as ca } from "./assets/icons/qrb.svg.js";
129
129
  import { default as Ia } from "./assets/icons/question-mark.svg.js";
130
130
  import { default as _a } from "./assets/icons/quotes.svg.js";
131
- import { default as Oa } from "./assets/icons/RCS_PDF.svg.js";
131
+ import { default as Ra } from "./assets/icons/RCS_PDF.svg.js";
132
132
  import { default as ga } from "./assets/icons/redirect.svg.js";
133
133
  import { default as La } from "./assets/icons/RedirectToNew.svg.js";
134
134
  import { default as Da } from "./assets/icons/refresh.svg.js";
@@ -155,7 +155,7 @@ import { default as Ap } from "./assets/icons/StoreIcon.js";
155
155
  import { default as cp } from "./assets/icons/strikeThrough.svg.js";
156
156
  import { default as Ip } from "./assets/icons/sub_category.svg.js";
157
157
  import { default as _p } from "./assets/icons/successIcon.svg.js";
158
- import { default as Op } from "./assets/icons/SupportIcon.js";
158
+ import { default as Rp } from "./assets/icons/SupportIcon.js";
159
159
  import { default as gp } from "./assets/icons/sync.svg.js";
160
160
  import { default as Lp } from "./assets/icons/task.svg.js";
161
161
  import { default as Dp } from "./assets/icons/text_t9.svg.js";
@@ -180,7 +180,7 @@ import { default as uf } from "./assets/icons/whatsapp-channel.svg.js";
180
180
  import { default as Cf } from "./components/channel-playground/portable/channels/whatsapp/index.js";
181
181
  import { default as Sf } from "./assets/icons/whatsapp_color.svg.js";
182
182
  import { default as Ef } from "./assets/icons/WhiteStarFilled.svg.js";
183
- import { ACTIONS_TYPES as Pf, CUSTOM_URL_NAME as _f, HEADER_TYPES as Rf, STATIC_URL_CTA_OPTION as Of, TEMPLATE_EDITOR as hf, TEMPLATE_STATUS as gf, UNSUBSCRIBE_URL_OPTION as Nf } from "./components/template-preview/models/TemplateMeta.js";
183
+ import { ACTIONS_TYPES as Pf, CUSTOM_URL_NAME as _f, HEADER_TYPES as Of, STATIC_URL_CTA_OPTION as Rf, TEMPLATE_EDITOR as hf, TEMPLATE_STATUS as gf, UNSUBSCRIBE_URL_OPTION as Nf } from "./components/template-preview/models/TemplateMeta.js";
184
184
  import { AD_STRING_OPERATORS as Bf, ANY_AD_OPERATORS as Df, ANY_IG_OPERATORS as Mf, BOOLEAN_OPERATORS as yf, DATE_OPERATORS as kf, EVENT_VALUES as Ff, EXACTLY_OPERATORS as Uf, FREQUENCY_OPERATORS as bf, ICE_BREAKER_OPERATORS as Hf, IG_STRING_OPERATORS as wf, INTEGER_OPERATORS as Gf, MAIL_SUBJECT_OPERATORS as Vf, REACTION_OPERATORS as vf, SPECIFIC_IG_OPERATORS as Wf, STRING_OPERATORS as Yf, STRING_RESTRICTED_OPERATORS as Kf, STRING_RESTRICTED_OPERATORS_2 as zf, STRING_RESTRICTED_OPERATORS_3 as Xf } from "./components/QueryBuilder/types/QueryBuilderOperator.type.js";
185
185
  import { AGENTIC_BUILDER_NODE_ID as jf, MANIFEST_AGENTIC_PATH as Zf, buildAgenticRequest as qf, streamAgenticReply as Jf } from "./components/channel-playground/portable/agenticService.js";
186
186
  import { AGENT_CHANNEL_TYPES as om, CHANNEL_PRESENTATION as rm, channelPresentation as em } from "./components/agent-builder/constants/channels.js";
@@ -190,7 +190,7 @@ import { AIChat as sm } from "./components/bik-chatbot/components/AIChat.js";
190
190
  import { AIProvider as um, useAIContext as Tm } from "./components/bik-chatbot/contexts/AIContext.js";
191
191
  import { AI_TAG_CHANGE_RATIO_THRESHOLD as Am, computeAiTagOnAccept as Sm, levenshteinDistance as cm } from "./components/WhatsAppTextEditor/ai/aiTag.js";
192
192
  import { ALERT_TYPES as Im, COLOR_CONFIG_MAP as Pm, CONTENT_POSITION as _m } from "./components/alerts/AlertHelper.js";
193
- import { ANIMATION_TIMING as Om } from "./components/feature-announcements/constants/animations.js";
193
+ import { ANIMATION_TIMING as Rm } from "./components/feature-announcements/constants/animations.js";
194
194
  import { APIError as gm } from "./utils/logging/ErrorConstructor/ApiError.js";
195
195
  import { APP_TOKEN as Lm, STEP_DEFINITIONS as Bm, resolveAppToken as Dm } from "./components/agent-builder/constants/steps.js";
196
196
  import { AVATAR_BACKGROUND as ym, AVATAR_SIZE_MAP as km, AVATAR_TYPES as Fm, SIZE as Um } from "./components/avatar/AvatarHelper.js";
@@ -212,7 +212,7 @@ import { Alert as Tl } from "./components/alerts/Alert.js";
212
212
  import { AnalyticsCard as Al } from "./components/analytics-card/AnalyticsCard.js";
213
213
  import { AnalyticsChip as cl } from "./components/analytics-chips-and-dropdowns/AnalyticsChip.js";
214
214
  import { AnalyticsContainer as Il, CardDataContainer as Pl } from "./components/analytics-card/AnalyticsCard.styled.js";
215
- import { AnalyticsDropdown as Rl, EachItem as Ol, formatDate as hl } from "./components/analytics-chips-and-dropdowns/AnalyticsDropdown.js";
215
+ import { AnalyticsDropdown as Ol, EachItem as Rl, formatDate as hl } from "./components/analytics-chips-and-dropdowns/AnalyticsDropdown.js";
216
216
  import { AnalyticsItem as Nl, QualityTimelineChart as Ll, RightPanelTemplateAnalytics as Bl, TemplateAnalyticsComponent as Dl } from "./components/template-context-mapper/modalElements/TemplateAnalyticsComponent.js";
217
217
  import { AnalyticsMetric as yl } from "./components/analytics-chips-and-dropdowns/AnalyticsMetric.js";
218
218
  import { AnalyticsMultiChip as Fl } from "./components/analytics-chips-and-dropdowns/AnalyticsMultiChip.js";
@@ -227,7 +227,7 @@ import { BaseQueryBuilderNode as Ci } from "./components/QueryBuilder/components
227
227
  import { BaseWhatsappContentLangHelper as Si } from "./helpers/BaseWhatsappContentLang.helper.js";
228
228
  import { BikAccordion as Ei } from "./components/accordion/Accordion.js";
229
229
  import { BikEditor as Pi } from "./editor/BikEditor.js";
230
- import { BikEditorToolbar as Ri } from "./editor/toolbar/BikEditorToolbar.js";
230
+ import { BikEditorToolbar as Oi } from "./editor/toolbar/BikEditorToolbar.js";
231
231
  import { default as hi } from "./components/BikGiftedChat/GiftedChat/GiftedChat.js";
232
232
  import { BikHeader as Ni } from "./components/bik-layout/BikHeader.js";
233
233
  import { BikImageCropper as Bi } from "./components/image-cropper/BikImageCropper.js";
@@ -248,7 +248,7 @@ import { CHANNEL_TYPE as xn } from "./components/template-preview/models/Channel
248
248
  import { CHAT_MESSAGE_ROLES as dn, DEFAULT_CONVERSATION_ID as un, createSessionRecord as Tn } from "./components/bik-chatbot/types/chat.js";
249
249
  import { COPILOT_BALL_ATTRIBUTE as An, CopilotBall as Sn } from "./components/bik-copilot/CopilotBall.js";
250
250
  import { COPILOT_ENDPOINT_PATH as En, streamCopilotChat as In } from "./components/bik-copilot/services/copilotStreamClient.js";
251
- import { COPILOT_FEEDBACK_PATH as _n, sendCopilotFeedback as Rn } from "./components/bik-copilot/services/copilotFeedbackClient.js";
251
+ import { COPILOT_FEEDBACK_PATH as _n, sendCopilotFeedback as On } from "./components/bik-copilot/services/copilotFeedbackClient.js";
252
252
  import { COPILOT_FEEDBACK_REASONS as hn, CopilotFeedbackModal as gn } from "./components/bik-copilot/CopilotFeedbackModal.js";
253
253
  import { COPILOT_HISTORY_PAGE_SIZE as Ln, COPILOT_MESSAGES_PATH as Bn, fetchCopilotMessages as Dn } from "./components/bik-copilot/services/copilotMessagesClient.js";
254
254
  import { COPILOT_ICEBREAKERS_PATH as yn, fetchCopilotIcebreakers as kn } from "./components/bik-copilot/services/copilotIcebreakersClient.js";
@@ -261,7 +261,7 @@ import { CardSelectionModal as Ax } from "./components/card-selection-modal/Card
261
261
  import { CardSelector as cx } from "./components/card-selector/CardSelector.js";
262
262
  import { CardSelectorGroup as Ix } from "./components/card-selector/CardSelectorGroup.js";
263
263
  import { Carousel as _x } from "./components/carousel/carousel.js";
264
- import { CarouselPreview as Ox } from "./components/carousel-preview/CarouselPreview.js";
264
+ import { CarouselPreview as Rx } from "./components/carousel-preview/CarouselPreview.js";
265
265
  import { CarouselSecondary as gx } from "./components/carousel-secondary/CarouselSecondary.js";
266
266
  import { CarouselVersion as Lx } from "./components/carousel-secondary/model.js";
267
267
  import { Channels as Dx } from "@bikdotai/bik-models/campaigns/models/Channel";
@@ -287,7 +287,7 @@ import { CouponExpiration as Cs } from "./components/discount-modal/CouponExpira
287
287
  import { CurrencySymbols as Ss } from "./components/product-picker-v2/constants.js";
288
288
  import { Curtain as Es } from "./components/curtain/Curtain.js";
289
289
  import { CustomDateTime as Ps } from "./components/custom-date-time/CustomDateTime.js";
290
- import { CustomError as Rs } from "./utils/logging/ErrorConstructor/CustomError.js";
290
+ import { CustomError as Os } from "./utils/logging/ErrorConstructor/CustomError.js";
291
291
  import { DEFAULT_FORMAT_STATE as hs } from "./editor/BikEditor.types.js";
292
292
  import { DEFAULT_COPILOT_AGENT as Ns, DEFAULT_COPILOT_ROUTE as Ls, useCopilotIcebreakers as Bs } from "./components/bik-copilot/useCopilotIcebreakers.js";
293
293
  import { DEFAULT_IMAGE as Ms, ShimmerImage as ys } from "./components/shimmer-image/ShimmerImage.js";
@@ -307,7 +307,7 @@ import { DropdownButton as Ad } from "./components/dropdown-button/DropdownButto
307
307
  import { DropdownPopover as cd } from "./components/dropdown/DropdownPopover/index.js";
308
308
  import { DualIconButton as Id } from "./components/dual-icon-button/DualIconButton.js";
309
309
  import { DurationUnit as _d } from "./components/analytics-chips-and-dropdowns/chart/scoreBlock/types.js";
310
- import { DynamicTabs as Od } from "./components/dynamic-tabs/DynamicTabs.js";
310
+ import { DynamicTabs as Rd } from "./components/dynamic-tabs/DynamicTabs.js";
311
311
  import { ERROR_TYPES as gd, ERROR_TYPE_CLASS_MAP as Nd, Logger as Ld } from "./utils/logging/Logger.js";
312
312
  import { ExcelUploadError as Dd } from "./utils/logging/ErrorConstructor/ExcelUploadError.js";
313
313
  import { FABMenu as yd } from "./components/fab-menu/FABMenu.js";
@@ -329,7 +329,7 @@ import { HalfDoughnutChart as Tu } from "./components/half-doughnut-chart/HalfDo
329
329
  import { HeatBoxStyled as Au, HeatMapVertical as Su } from "./components/analytics-chips-and-dropdowns/chart/heatmap/HeatMapVertical.js";
330
330
  import { HorinzontalBar as Eu } from "./components/analytics-chips-and-dropdowns/chart/scoreBlock/HorizontalBar.js";
331
331
  import { HorizontalGraph as Pu } from "./components/analytics-chips-and-dropdowns/chart/HorizontalBarGraph/HorizontalGraph.js";
332
- import { IconButton as Ru } from "./components/icon-button/IconButton.js";
332
+ import { IconButton as Ou } from "./components/icon-button/IconButton.js";
333
333
  import { ImageService as hu } from "./components/image-compress/ImageCompress.js";
334
334
  import { InactiveChecklistIcon as Nu } from "./assets/icons/InactiveChecklistIcon.js";
335
335
  import { Input as Bu } from "./components/input/Input.js";
@@ -351,7 +351,7 @@ import { POPUP_DIMENSIONS as AT } from "./components/feature-announcements/const
351
351
  import { Pagination as cT } from "./components/pagination/Pagination.js";
352
352
  import { PickerType as IT } from "./components/variable-picker-v3/model.js";
353
353
  import { PieChart as _T } from "./components/analytics-chips-and-dropdowns/chart/Pie/PieChart.js";
354
- import { PostLiveChecklist as OT } from "./components/post-live-checklist/PostLiveChecklist.js";
354
+ import { PostLiveChecklist as RT } from "./components/post-live-checklist/PostLiveChecklist.js";
355
355
  import { PostLiveChecklistItem as gT } from "./components/post-live-checklist-item/PostLiveChecklistItem.js";
356
356
  import { PricePleaseProductPicker as LT, ProductPickerContent as BT } from "./components/product-picker/ProductPickerModal.js";
357
357
  import { ProductPickerModal as MT } from "./components/product-picker-v2/modal.js";
@@ -373,7 +373,7 @@ import { SELECTION_ASK_TARGET as AC } from "./components/text-selection-ask/mode
373
373
  import { ScoreBlock as cC } from "./components/analytics-chips-and-dropdowns/chart/scoreBlock/ScoreBlock.js";
374
374
  import { SearchBar as IC } from "./components/searchBar/searchBar.js";
375
375
  import { SearchIcon as _C } from "./assets/icons/searchIcon.js";
376
- import { ShopifyScopeWrapper as OC } from "./components/states/ShopifyScopeWrapper.js";
376
+ import { ShopifyScopeWrapper as RC } from "./components/states/ShopifyScopeWrapper.js";
377
377
  import { ShowShopifyRestrictedModal as gC } from "./components/bik-layout/ShowShopifyRestrictedModal.js";
378
378
  import { SideModal as LC } from "./components/side-modal/SideModal.js";
379
379
  import { SidebarSkeleton as DC } from "./components/bik-layout/SidebarSkeleton.js";
@@ -399,7 +399,7 @@ import { TestimonialCard as AA } from "./components/testimonial-card/Testimonial
399
399
  import { TestingPlayground as cA } from "./components/channel-playground/TestingPlayground.js";
400
400
  import { TestingPlaygroundModal as IA } from "./components/channel-playground/TestingPlaygroundModal.js";
401
401
  import { TextPickerModal as _A } from "./components/text-picker/TextPickerModal.js";
402
- import { TimePicker as OA } from "./components/datePicker/TimePicker.js";
402
+ import { TimePicker as RA } from "./components/datePicker/TimePicker.js";
403
403
  import { Toaster as gA } from "./components/toaster/Toaster.js";
404
404
  import { ToolSource as LA } from "./components/agent-builder/constants/tools.js";
405
405
  import { Tooltip as DA } from "./components/tooltips/Tooltip.js";
@@ -419,8 +419,8 @@ import { WhatsappIntegrationError as CS } from "./utils/logging/ErrorConstructor
419
419
  import { WhatsappLikePreview as SS } from "./components/template-preview/WhatsApp/WhatsAppLikePreview.js";
420
420
  import { WhatsappLikePreviewV2 as ES } from "./components/template-preview/WhatsApp/WhatsAppLikePreviewV2.js";
421
421
  import { apiInfoFromError as PS, callWithTiming as _S } from "./components/channel-playground/portable/transport.js";
422
- import { buildAgentMentionItems as OS, editorDocToInstructions as hS, instructionsToEditorHtml as gS } from "./components/agent-builder/utils/mentionSerialization.js";
423
- import { clearCopilotPageSessions as LS, getCopilotSessionIdForRoute as BS, resetCopilotSessionForRoute as DS, resolveCopilotSessionIdForRoute as MS } from "./components/bik-copilot/services/copilotPageSession.js";
422
+ import { buildAgentMentionItems as RS, editorDocToInstructions as hS, instructionsToEditorHtml as gS } from "./components/agent-builder/utils/mentionSerialization.js";
423
+ import { clearCopilotPageSessions as LS, getCopilotSessionId as BS, resetCopilotSession as DS, resolveCopilotSessionId as MS } from "./components/bik-copilot/services/copilotPageSession.js";
424
424
  import { createBikTransport as kS } from "./components/channel-playground/transport/createBikTransport.js";
425
425
  import { environment as US } from "./firebase/environment.js";
426
426
  import { escapeFormulaInjection as HS, isAllowedImageUrl as wS, isAllowedLinkUrl as GS, isAllowedUrl as VS, sanitizeBasicHtml as vS, sanitizeCssProperties as WS, sanitizeEmailHtml as YS, sanitizePlainText as KS, stripHtmlTags as zS } from "./helpers/sanitize.js";
@@ -435,7 +435,7 @@ import { isVariable as Tc, validateIsUrl as Cc } from "./components/template-con
435
435
  import { queryBuilderCacheSlice as Sc } from "./components/QueryBuilder/redux/queryBuilderCache.reducer.js";
436
436
  import { queryBuilderSlice as Ec } from "./components/QueryBuilder/redux/queryBuilder.reducer.js";
437
437
  import { renderVariableUIForPreview as Pc } from "./components/template-preview/helpers/SmsTemplateHelper.js";
438
- import { resizeImage as Rc } from "./utils/resizeImage.js";
438
+ import { resizeImage as Oc } from "./utils/resizeImage.js";
439
439
  import { toLiveChatText as hc } from "./editor/serializers/toLiveChatText.js";
440
440
  import { toWhatsAppText as Nc } from "./editor/serializers/toWhatsAppText.js";
441
441
  import { unwrapDropdownValue as Bc } from "./components/dropdown/utils.js";
@@ -459,7 +459,7 @@ export {
459
459
  um as AIProvider,
460
460
  Am as AI_TAG_CHANGE_RATIO_THRESHOLD,
461
461
  Im as ALERT_TYPES,
462
- Om as ANIMATION_TIMING,
462
+ Rm as ANIMATION_TIMING,
463
463
  Df as ANY_AD_OPERATORS,
464
464
  Mf as ANY_IG_OPERATORS,
465
465
  gm as APIError,
@@ -495,13 +495,13 @@ export {
495
495
  Al as AnalyticsCard,
496
496
  cl as AnalyticsChip,
497
497
  Il as AnalyticsContainer,
498
- Rl as AnalyticsDropdown,
498
+ Ol as AnalyticsDropdown,
499
499
  Nl as AnalyticsItem,
500
500
  yl as AnalyticsMetric,
501
501
  Fl as AnalyticsMultiChip,
502
502
  bl as AnalyticsTrend,
503
503
  _o as ArrowBack,
504
- Oo as ArrowDown,
504
+ Ro as ArrowDown,
505
505
  go as ArrowLeft,
506
506
  Lo as ArrowUp,
507
507
  wm as Avatar,
@@ -521,7 +521,7 @@ export {
521
521
  Ei as BikAccordion,
522
522
  yo as BikAiStarsIcon,
523
523
  Pi as BikEditor,
524
- Ri as BikEditorToolbar,
524
+ Oi as BikEditorToolbar,
525
525
  hi as BikGiftedChat,
526
526
  Ni as BikHeader,
527
527
  Bi as BikImageCropper,
@@ -557,8 +557,8 @@ export {
557
557
  rn as Button,
558
558
  tn as ButtonActions,
559
559
  ln as ButtonGroup,
560
- R as ButtonLarge,
561
- O as ButtonLargeAI,
560
+ O as ButtonLarge,
561
+ R as ButtonLargeAI,
562
562
  h as ButtonRegular,
563
563
  g as ButtonRegularAI,
564
564
  an as ButtonTypes,
@@ -593,7 +593,7 @@ export {
593
593
  cx as CardSelector,
594
594
  Ix as CardSelectorGroup,
595
595
  _x as Carousel,
596
- Ox as CarouselPreview,
596
+ Rx as CarouselPreview,
597
597
  gx as CarouselSecondary,
598
598
  Lx as CarouselVersion,
599
599
  Dx as Channels,
@@ -611,7 +611,7 @@ export {
611
611
  cr as ChevronDown,
612
612
  Ir as ChevronDownOutline,
613
613
  _r as ChevronLeft,
614
- Or as ChevronLeft2,
614
+ Rr as ChevronLeft2,
615
615
  gr as ChevronRight,
616
616
  Lr as ChevronRight2,
617
617
  Dr as ChevronRightAlt,
@@ -648,7 +648,7 @@ export {
648
648
  to as CustomDataCategories,
649
649
  ao as CustomDataType,
650
650
  Ps as CustomDateTime,
651
- Rs as CustomError,
651
+ Os as CustomError,
652
652
  j as CustomPortal,
653
653
  lm as CustomRightBorder,
654
654
  jr as CustomiseIcon,
@@ -689,13 +689,13 @@ export {
689
689
  Gs as DropdownToggleContainer,
690
690
  Id as DualIconButton,
691
691
  _d as DurationUnit,
692
- Od as DynamicTabs,
692
+ Rd as DynamicTabs,
693
693
  Kl as EMAIL_PATTERN,
694
694
  gd as ERROR_TYPES,
695
695
  Nd as ERROR_TYPE_CLASS_MAP,
696
696
  Ff as EVENT_VALUES,
697
697
  Uf as EXACTLY_OPERATORS,
698
- Ol as EachItem,
698
+ Rl as EachItem,
699
699
  ie as Edit,
700
700
  xe as EditLabel,
701
701
  im as EditorActionTypes,
@@ -706,7 +706,7 @@ export {
706
706
  Ie as ErrorIcon,
707
707
  _e as ErrorInfo,
708
708
  Dd as ExcelUploadError,
709
- Oe as ExpressionlessEmoji,
709
+ Re as ExpressionlessEmoji,
710
710
  yd as FABMenu,
711
711
  Vs as FAB_POSITION,
712
712
  l as FONTS,
@@ -734,7 +734,7 @@ export {
734
734
  we as GoLiveIcon,
735
735
  Ve as Graph,
736
736
  We as Grid,
737
- Rf as HEADER_TYPES,
737
+ Of as HEADER_TYPES,
738
738
  pu as HEAT,
739
739
  fu as HEAT_COLORS,
740
740
  mu as HEAT_GRADING_TYPE,
@@ -758,7 +758,7 @@ export {
758
758
  wf as IG_STRING_OPERATORS,
759
759
  Gf as INTEGER_OPERATORS,
760
760
  zl as ITALIC_TEXT_PATTERN,
761
- Ru as IconButton,
761
+ Ou as IconButton,
762
762
  pt as Idea,
763
763
  mt as Image,
764
764
  hu as ImageService,
@@ -779,7 +779,7 @@ export {
779
779
  zu as ListItem,
780
780
  Qu as Loader,
781
781
  _t as Locked,
782
- Ot as LogOut,
782
+ Rt as LogOut,
783
783
  Ld as Logger,
784
784
  gt as LtoIcon,
785
785
  Vf as MAIL_SUBJECT_OPERATORS,
@@ -829,7 +829,7 @@ export {
829
829
  ia as Plus,
830
830
  xa as PlusIcon,
831
831
  da as Pointer,
832
- OT as PostLiveChecklist,
832
+ RT as PostLiveChecklist,
833
833
  gT as PostLiveChecklistItem,
834
834
  od as PostPicker,
835
835
  LT as PricePleaseProductPicker,
@@ -853,7 +853,7 @@ export {
853
853
  _a as Quotes,
854
854
  $T as RATIO,
855
855
  Ql as RAW_PHONE_CANDIDATE_PATTERN,
856
- Oa as RCSPDF,
856
+ Ra as RCSPDF,
857
857
  vf as REACTION_OPERATORS,
858
858
  bs as RESPONSE_FORMATS,
859
859
  eC as RadioButton,
@@ -873,7 +873,7 @@ export {
873
873
  AC as SELECTION_ASK_TARGET,
874
874
  Um as SIZE,
875
875
  Wf as SPECIFIC_IG_OPERATORS,
876
- Of as STATIC_URL_CTA_OPTION,
876
+ Rf as STATIC_URL_CTA_OPTION,
877
877
  Bm as STEP_DEFINITIONS,
878
878
  Yf as STRING_OPERATORS,
879
879
  Kf as STRING_RESTRICTED_OPERATORS,
@@ -892,7 +892,7 @@ export {
892
892
  Ka as SendTemplate,
893
893
  ys as ShimmerImage,
894
894
  Xa as ShippingIcon,
895
- OC as ShopifyScopeWrapper,
895
+ RC as ShopifyScopeWrapper,
896
896
  ja as ShoppingIcon,
897
897
  gC as ShowShopifyRestrictedModal,
898
898
  LC as SideModal,
@@ -929,7 +929,7 @@ export {
929
929
  Qi as SubscriptionPlanSelector,
930
930
  qC as SubscriptionPlansCollected,
931
931
  _p as SuccessIcon,
932
- Op as SupportIcon,
932
+ Rp as SupportIcon,
933
933
  ju as Switch,
934
934
  Zu as SwitchContainer,
935
935
  gp as Sync,
@@ -962,7 +962,7 @@ export {
962
962
  oC as Thumbnail,
963
963
  Fp as Tick,
964
964
  bp as TickDouble,
965
- OA as TimePicker,
965
+ RA as TimePicker,
966
966
  k as Tiny,
967
967
  F as TitleFour,
968
968
  U as TitleLarge,
@@ -1016,7 +1016,7 @@ export {
1016
1016
  ES as WhatsappLikePreviewV2,
1017
1017
  Ef as WhiteStarFilled,
1018
1018
  PS as apiInfoFromError,
1019
- OS as buildAgentMentionItems,
1019
+ RS as buildAgentMentionItems,
1020
1020
  qf as buildAgenticRequest,
1021
1021
  kA as calculatePercentage,
1022
1022
  _S as callWithTiming,
@@ -1044,7 +1044,7 @@ export {
1044
1044
  qS as getAuthMethods,
1045
1045
  ac as getBodyHtml,
1046
1046
  mc as getCopilotPanelPlacement,
1047
- BS as getCopilotSessionIdForRoute,
1047
+ BS as getCopilotSessionId,
1048
1048
  ic as getFireStoreDb,
1049
1049
  xc as getFireStoreLiteDb,
1050
1050
  dc as getFirebaseChatStorage,
@@ -1081,10 +1081,10 @@ export {
1081
1081
  Ec as queryBuilderSlice,
1082
1082
  o as regexPatterns,
1083
1083
  Pc as renderVariableUIForPreview,
1084
- DS as resetCopilotSessionForRoute,
1085
- Rc as resizeImage,
1084
+ DS as resetCopilotSession,
1085
+ Oc as resizeImage,
1086
1086
  Dm as resolveAppToken,
1087
- MS as resolveCopilotSessionIdForRoute,
1087
+ MS as resolveCopilotSessionId,
1088
1088
  Gu as rnSecondaryAuth,
1089
1089
  FA as roundNumber,
1090
1090
  vS as sanitizeBasicHtml,
@@ -1092,7 +1092,7 @@ export {
1092
1092
  YS as sanitizeEmailHtml,
1093
1093
  KS as sanitizePlainText,
1094
1094
  qn as saveCopilotSession,
1095
- Rn as sendCopilotFeedback,
1095
+ On as sendCopilotFeedback,
1096
1096
  Jf as streamAgenticReply,
1097
1097
  In as streamCopilotChat,
1098
1098
  zS as stripHtmlTags,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bikdotai/bik-component-library",
3
- "version": "0.0.876",
3
+ "version": "0.0.877-beta.0",
4
4
  "description": "Bik Component Library",
5
5
  "repository": {
6
6
  "type": "git",