@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.
- package/dist/cjs/components/bik-copilot/services/copilotDb.js +1 -1
- package/dist/cjs/components/bik-copilot/services/copilotDb.js.map +1 -1
- package/dist/cjs/components/bik-copilot/services/copilotPageSession.js +1 -1
- package/dist/cjs/components/bik-copilot/services/copilotPageSession.js.map +1 -1
- package/dist/cjs/components/bik-copilot/useCopilotStreamChat.js +1 -1
- package/dist/cjs/components/bik-copilot/useCopilotStreamChat.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/bik-copilot/index.d.ts +1 -1
- package/dist/esm/components/bik-copilot/services/copilotDb.d.ts +15 -17
- package/dist/esm/components/bik-copilot/services/copilotDb.js +49 -57
- package/dist/esm/components/bik-copilot/services/copilotDb.js.map +1 -1
- package/dist/esm/components/bik-copilot/services/copilotPageSession.d.ts +10 -13
- package/dist/esm/components/bik-copilot/services/copilotPageSession.js +22 -25
- package/dist/esm/components/bik-copilot/services/copilotPageSession.js.map +1 -1
- package/dist/esm/components/bik-copilot/useCopilotStreamChat.js +95 -96
- package/dist/esm/components/bik-copilot/useCopilotStreamChat.js.map +1 -1
- package/dist/esm/index.js +49 -49
- package/package.json +1 -1
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
423
|
-
import { clearCopilotPageSessions as LS,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
561
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
1085
|
-
|
|
1084
|
+
DS as resetCopilotSession,
|
|
1085
|
+
Oc as resizeImage,
|
|
1086
1086
|
Dm as resolveAppToken,
|
|
1087
|
-
MS as
|
|
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
|
-
|
|
1095
|
+
On as sendCopilotFeedback,
|
|
1096
1096
|
Jf as streamAgenticReply,
|
|
1097
1097
|
In as streamCopilotChat,
|
|
1098
1098
|
zS as stripHtmlTags,
|