@navsi.ai/sdk 1.0.6 → 1.0.7
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/chunk-FTD7P2DD.js +2 -0
- package/dist/chunk-FTD7P2DD.js.map +1 -0
- package/dist/{chunk-CH74WH2N.js → chunk-MORKY4MY.js} +3 -3
- package/dist/{chunk-CH74WH2N.js.map → chunk-MORKY4MY.js.map} +1 -1
- package/dist/components/index.js +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-UWRZ4ZYG.js +0 -2
- package/dist/chunk-UWRZ4ZYG.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {createContext,useContext,useMemo,useState,useRef,useEffect,useCallback}from'react';var q=createContext(null);function C(){let e=useContext(q);if(!e)throw new Error("useChatbotContext must be used within a ChatbotProvider");return e}function ee(){let e=C();return {widgetConfig:e.widgetConfig,voiceLanguage:e.voiceLanguage,setVoiceLanguage:e.setVoiceLanguage,messages:e.messages,sendMessage:e.sendMessage,clearMessages:e.clearMessages,mode:e.mode,setMode:e.setMode,isWidgetOpen:e.isWidgetOpen,setWidgetOpen:e.setWidgetOpen,isConnected:e.isConnected,connect:e.connect,disconnect:e.disconnect,executeAction:e.executeAction,registerServerAction:e.registerServerAction,stopExecution:e.stopExecution,isExecuting:e.isExecuting,error:e.error,clearError:e.clearError}}function oe(){let e=C(),r=e.executionState?{current:e.executionState.currentIndex,total:e.executionState.totalCommands,percentage:e.executionState.totalCommands>0?Math.round(e.executionState.currentIndex/e.executionState.totalCommands*100):0,description:e.executionState.description}:null;return {isExecuting:e.isExecuting,executionState:e.executionState,currentCommand:e.executionState?.currentCommand,progress:r}}function ce(){let e=C();return {connectionState:e.connectionState,isConnected:e.connectionState==="connected",isConnecting:e.connectionState==="connecting",isReconnecting:e.connectionState==="reconnecting",connect:e.connect,disconnect:e.disconnect}}function Y(){if(typeof window>"u")return null;let e=window;return e.SpeechRecognition??e.webkitSpeechRecognition??null}var j=typeof navigator<"u"&&"brave"in navigator;function z(e){switch(e){case "network":return typeof navigator<"u"&&!navigator.onLine?"You appear to be offline \u2014 voice needs a network connection.":j?"Brave may block speech services. Disable Shields or try Chrome/Edge.":typeof window<"u"&&window.location.protocol!=="https:"&&!["localhost","127.0.0.1"].includes(window.location.hostname)?"Microphone access requires HTTPS.":"Network error \u2014 check mic permissions and reload.";case "not-allowed":case "service-not-allowed":return "Microphone permission is blocked.";case "no-speech":return "No speech detected \u2014 try again.";case "audio-capture":return "No microphone found.";case "aborted":return "";default:return `Voice error: ${e}`}}function G(e){return e.replace(/\*\*(.*?)\*\*/g,"$1").replace(/[*_~`#]/g,"").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/\n{2,}/g,". ").trim()}function J(e,r=120){let S=e.replace(/(\d)\.(\d)/g,"$1\u2038$2").match(/[^.!?।:;\n]+[.!?।:;\n]+[\s]*/g),b=S?S.map(c=>c.replace(new RegExp("\u2038","g"),".")):[e],l=[],s="";for(let c of b)s.length+c.length>r&&s&&(l.push(s.trim()),s=""),s+=c;s.trim()&&l.push(s.trim());let d=[];for(let c of l)if(c.length<=r)d.push(c);else {let o=c;for(;o.length>r;){let g=o.lastIndexOf(",",r);g<r/2&&(g=o.lastIndexOf(" ",r)),g<1&&(g=r),d.push(o.slice(0,g+1).trim()),o=o.slice(g+1).trim();}o&&d.push(o);}return d}function ae({lang:e,onTranscript:r,silenceMs:W=1200,autoSpeak:O=true}){let S=useMemo(Y,[]),[b,l]=useState(false),[s,d]=useState(""),[c,o]=useState(null),[g,R]=useState(false),p=useRef(null),m=useRef(""),k=useRef(null),V=useRef(r),M=useRef(e),T=useRef(false),t=useRef(true),A=useRef(null),U=useRef(0);V.current=r,M.current=e,useEffect(()=>{if(T.current||typeof window>"u"||!("speechSynthesis"in window))return;T.current=true;let n=new SpeechSynthesisUtterance("");n.volume=0,window.speechSynthesis.speak(n);},[]);let f=useCallback(()=>{k.current&&(clearTimeout(k.current),k.current=null);},[]),L=useCallback(()=>{let n=m.current.trim();m.current="",t.current&&(d(""),n&&V.current(n));},[]),P=useCallback(()=>{if(!S)return null;if(p.current)return p.current.lang=M.current,p.current;let n=new S;return n.continuous=true,n.interimResults=true,n.maxAlternatives=1,n.lang=M.current,n.onstart=()=>{t.current&&(l(true),o(null),d(""),m.current="",typeof window<"u"&&"speechSynthesis"in window&&window.speechSynthesis.cancel());},n.onresult=u=>{if(!t.current)return;let v="";for(let w=u.resultIndex;w<u.results.length;w++){let x=u.results[w],E=x[0]?.transcript??"";x.isFinal?m.current=(m.current+" "+E).trim():v+=E;}d(m.current?m.current:v.trim()),f(),k.current=setTimeout(()=>{t.current&&(p.current?.stop(),L(),l(false));},W);},n.onerror=u=>{if(!t.current)return;let v=z(u.error);v&&o(v),["not-allowed","service-not-allowed","audio-capture"].includes(u.error)&&(f(),l(false));},n.onend=()=>{t.current&&(f(),L(),l(false));},p.current=n,n},[S,f,L,W]),D=useCallback(()=>{if(b)return;o(null);let n=P();if(!n){o("Voice input is not supported in this browser.");return}try{n.start();}catch{}},[b,P]),H=useCallback(()=>{f();try{p.current?.stop();}catch{}},[f]),i=useCallback(()=>{A.current&&(clearInterval(A.current),A.current=null);},[]),N=useCallback(n=>{if(typeof window>"u"||!("speechSynthesis"in window)||!O)return;let u=G(n);if(!u)return;window.speechSynthesis.cancel(),i();let v=++U.current,w=J(u),x=0,E=()=>{if(U.current!==v||!t.current){i(),t.current&&R(false);return}if(x>=w.length){i(),t.current&&R(false);return}let y=new SpeechSynthesisUtterance(w[x]);y.lang=M.current,x++,y.onstart=()=>{i(),A.current=setInterval(()=>{window.speechSynthesis.speaking&&!window.speechSynthesis.paused&&(window.speechSynthesis.pause(),window.speechSynthesis.resume());},5e3);},y.onend=()=>{i(),E();},y.onerror=()=>{i(),t.current&&R(false);},window.speechSynthesis.speak(y);};t.current&&R(true),E();},[O,i]),B=useCallback(()=>{i(),typeof window<"u"&&"speechSynthesis"in window&&window.speechSynthesis.cancel(),t.current&&R(false);},[i]);return useEffect(()=>(t.current=true,()=>{t.current=false,f(),i(),p.current?.abort(),p.current=null,typeof window<"u"&&"speechSynthesis"in window&&window.speechSynthesis.cancel();}),[f,i]),{isSupported:!!S,isListening:b,transcript:s,error:c,start:D,stop:H,speak:N,cancelSpeech:B,isSpeaking:g}}export{q as a,C as b,ee as c,oe as d,ce as e,ae as f};//# sourceMappingURL=chunk-FTD7P2DD.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-FTD7P2DD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context/chatbot-context.tsx","../src/hooks/useChatbot.ts","../src/hooks/useActionExecution.ts","../src/hooks/useWebSocket.ts","../src/hooks/useVoice.ts"],"names":["ChatbotContext","createContext","useChatbotContext","context","useContext","useChatbot","useActionExecution","progress","useWebSocket","getRecognitionCtor","w","isBrave","friendlyError","code","stripMarkdown","text","splitIntoChunks","maxLen","parts","sentences","p","chunks","buf","s","result","remaining","idx","useVoice","lang","onTranscript","silenceMs","autoSpeak","Ctor","useMemo","isListening","setIsListening","useState","transcript","setTranscript","error","setError","isSpeaking","setIsSpeaking","recRef","useRef","finalBuf","silenceTimer","onTranscriptRef","langRef","ttsWarm","mountedRef","keepAliveRef","speakSessionRef","useEffect","u","clearSilence","useCallback","flushTranscript","getOrCreateRec","rec","ev","interim","i","seg","msg","start","stop","clearKeepAlive","speak","clean","session","speakNext","cancelSpeech"],"mappings":"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","file":"chunk-FTD7P2DD.js","sourcesContent":["/**\n * Chatbot Context\n * \n * React context for chatbot state and functionality.\n */\n\nimport { createContext, useContext } from 'react';\nimport type {\n Message,\n ChatMode,\n ConnectionState,\n ServerAction,\n ExecutionState,\n WidgetConfig,\n} from '@navsi.ai/shared';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ChatbotContextValue {\n /** Widget styling and copy (from admin / API). Applied by ChatbotWidget. */\n widgetConfig: Partial<WidgetConfig> | null;\n\n // State\n messages: Message[];\n mode: ChatMode;\n connectionState: ConnectionState;\n isExecuting: boolean;\n executionState: ExecutionState | null;\n error: Error | null;\n\n // Widget visibility (persists across navigation)\n isWidgetOpen: boolean;\n setWidgetOpen: (open: boolean) => void;\n\n /** User-selected voice/response language (e.g. 'en-US', 'hi-IN'). Overrides widgetConfig.voiceLanguage when set. */\n voiceLanguage: string | undefined;\n setVoiceLanguage: (lang: string | undefined) => void;\n\n // Actions\n sendMessage: (content: string) => void;\n setMode: (mode: ChatMode) => void;\n executeAction: (actionId: string, params?: Record<string, unknown>) => Promise<unknown>;\n registerServerAction: (action: ServerAction) => void;\n clearMessages: () => void;\n clearError: () => void;\n stopExecution: () => void;\n\n // Connection\n connect: () => void;\n disconnect: () => void;\n isConnected: boolean;\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nexport const ChatbotContext = createContext<ChatbotContextValue | null>(null);\n\n// ============================================================================\n// Hook\n// ============================================================================\n\n/**\n * Hook to access chatbot context\n * Must be used within ChatbotProvider\n */\nexport function useChatbotContext(): ChatbotContextValue {\n const context = useContext(ChatbotContext);\n\n if (!context) {\n throw new Error('useChatbotContext must be used within a ChatbotProvider');\n }\n\n return context;\n}\n","/**\n * useChatbot Hook\n * \n * Main hook for accessing chatbot functionality.\n * Provides simplified API for common operations.\n */\n\nimport { useChatbotContext } from '../context/chatbot-context.js';\nimport type { ChatMode, ServerAction, Message, WidgetConfig } from '@navsi.ai/shared';\n\nexport interface UseChatbotReturn {\n /** Widget styling/copy from admin (or options). Use in ChatbotWidget. */\n widgetConfig: Partial<WidgetConfig> | null;\n\n /** Effective voice/response language (user-selected or config). Use for STT/TTS and locale. */\n voiceLanguage: string | undefined;\n setVoiceLanguage: (lang: string | undefined) => void;\n\n // Messages\n messages: Message[];\n sendMessage: (content: string) => void;\n clearMessages: () => void;\n\n // Mode\n mode: ChatMode;\n setMode: (mode: ChatMode) => void;\n\n // Widget visibility (persists across navigation)\n isWidgetOpen: boolean;\n setWidgetOpen: (open: boolean) => void;\n\n // Connection\n isConnected: boolean;\n connect: () => void;\n disconnect: () => void;\n\n // Actions\n executeAction: (actionId: string, params?: Record<string, unknown>) => Promise<unknown>;\n registerServerAction: (action: ServerAction) => void;\n stopExecution: () => void;\n\n // State\n isExecuting: boolean;\n error: Error | null;\n clearError: () => void;\n}\n\n/**\n * Main hook for chatbot functionality\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const { \n * messages, \n * sendMessage, \n * isConnected,\n * mode,\n * setMode,\n * } = useChatbot();\n * \n * return (\n * <div>\n * <button onClick={() => sendMessage('Hello!')}>\n * Send\n * </button>\n * <button onClick={() => startVoice()}>\n * Start Voice\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useChatbot(): UseChatbotReturn {\n const context = useChatbotContext();\n\n return {\n widgetConfig: context.widgetConfig,\n voiceLanguage: context.voiceLanguage,\n setVoiceLanguage: context.setVoiceLanguage,\n // Messages\n messages: context.messages,\n sendMessage: context.sendMessage,\n clearMessages: context.clearMessages,\n\n // Mode\n mode: context.mode,\n setMode: context.setMode,\n\n // Widget visibility\n isWidgetOpen: context.isWidgetOpen,\n setWidgetOpen: context.setWidgetOpen,\n\n // Connection\n isConnected: context.isConnected,\n connect: context.connect,\n disconnect: context.disconnect,\n\n // Actions\n executeAction: context.executeAction,\n registerServerAction: context.registerServerAction,\n stopExecution: context.stopExecution,\n\n // State\n isExecuting: context.isExecuting,\n error: context.error,\n clearError: context.clearError,\n };\n}\n","/**\n * useActionExecution Hook\n * \n * Hook for monitoring action execution state.\n */\n\nimport { useChatbotContext } from '../context/chatbot-context.js';\nimport type { ExecutionState } from '@navsi.ai/shared';\n\nexport interface UseActionExecutionReturn {\n isExecuting: boolean;\n executionState: ExecutionState | null;\n currentCommand: ExecutionState['currentCommand'] | undefined;\n progress: {\n current: number;\n total: number;\n percentage: number;\n /** Optional human-readable description of the current step */\n description?: string;\n } | null;\n}\n\n/**\n * Hook for monitoring action execution\n */\nexport function useActionExecution(): UseActionExecutionReturn {\n const context = useChatbotContext();\n\n const progress = context.executionState\n ? {\n current: context.executionState.currentIndex,\n total: context.executionState.totalCommands,\n percentage: context.executionState.totalCommands > 0\n ? Math.round((context.executionState.currentIndex / context.executionState.totalCommands) * 100)\n : 0,\n description: context.executionState.description,\n }\n : null;\n\n return {\n isExecuting: context.isExecuting,\n executionState: context.executionState,\n currentCommand: context.executionState?.currentCommand,\n progress,\n };\n}\n","/**\n * useWebSocket Hook\n * \n * Hook for managing WebSocket connection state.\n */\n\nimport { useChatbotContext } from '../context/chatbot-context.js';\nimport type { ConnectionState } from '@navsi.ai/shared';\n\nexport interface UseWebSocketReturn {\n connectionState: ConnectionState;\n isConnected: boolean;\n isConnecting: boolean;\n isReconnecting: boolean;\n connect: () => void;\n disconnect: () => void;\n}\n\n/**\n * Hook for WebSocket connection management\n */\nexport function useWebSocket(): UseWebSocketReturn {\n const context = useChatbotContext();\n\n return {\n connectionState: context.connectionState,\n isConnected: context.connectionState === 'connected',\n isConnecting: context.connectionState === 'connecting',\n isReconnecting: context.connectionState === 'reconnecting',\n connect: context.connect,\n disconnect: context.disconnect,\n };\n}\n","/**\n * useVoice Hook — Low-latency STT + TTS for the Navsi chatbot.\n *\n * Design goals:\n * • Fast start: reuses a single SpeechRecognition instance across activations.\n * • Low latency: fires an auto-send after a configurable silence gap so the\n * user doesn't have to wait for the browser's default end-of-speech timeout.\n * • Clean separation: all voice state is encapsulated here; ChatbotWidget\n * only consumes the returned API.\n * • TTS warm-up: a silent utterance is queued once so the first real TTS play\n * doesn't incur a cold-start delay.\n *\n * Only depends on the Web Speech API — no extra packages.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\n// ---------------------------------------------------------------------------\n// Web Speech API type shims (not all TS libs ship these)\n// ---------------------------------------------------------------------------\n\ntype SpeechRecognitionCtor = new () => SpeechRecognitionInstance;\n\ninterface SpeechRecognitionInstance extends EventTarget {\n continuous: boolean;\n interimResults: boolean;\n maxAlternatives: number;\n lang: string;\n onstart: ((ev: Event) => void) | null;\n onend: ((ev: Event) => void) | null;\n onerror: ((ev: SpeechRecognitionErrorEvent) => void) | null;\n onresult: ((ev: SpeechRecognitionResultEvent) => void) | null;\n start: () => void;\n stop: () => void;\n abort: () => void;\n}\n\ninterface SpeechRecognitionErrorEvent extends Event {\n error: string;\n}\n\ninterface SpeechRecognitionResultEvent extends Event {\n resultIndex: number;\n results: SpeechRecognitionResultList;\n}\n\ninterface SpeechRecognitionResultList {\n length: number;\n [index: number]: SpeechRecognitionResultItem;\n}\n\ninterface SpeechRecognitionResultItem {\n isFinal: boolean;\n length: number;\n [index: number]: { transcript: string };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getRecognitionCtor(): SpeechRecognitionCtor | null {\n if (typeof window === 'undefined') return null;\n const w = window as Window & {\n SpeechRecognition?: SpeechRecognitionCtor;\n webkitSpeechRecognition?: SpeechRecognitionCtor;\n };\n return w.SpeechRecognition ?? w.webkitSpeechRecognition ?? null;\n}\n\nconst isBrave = typeof navigator !== 'undefined' && 'brave' in navigator;\n\nfunction friendlyError(code: string): string {\n switch (code) {\n case 'network': {\n if (typeof navigator !== 'undefined' && !navigator.onLine)\n return 'You appear to be offline — voice needs a network connection.';\n if (isBrave)\n return 'Brave may block speech services. Disable Shields or try Chrome/Edge.';\n if (\n typeof window !== 'undefined' &&\n window.location.protocol !== 'https:' &&\n !['localhost', '127.0.0.1'].includes(window.location.hostname)\n )\n return 'Microphone access requires HTTPS.';\n return 'Network error — check mic permissions and reload.';\n }\n case 'not-allowed':\n case 'service-not-allowed':\n return 'Microphone permission is blocked.';\n case 'no-speech':\n return 'No speech detected — try again.';\n case 'audio-capture':\n return 'No microphone found.';\n case 'aborted':\n return ''; // intentional abort — don't show an error\n default:\n return `Voice error: ${code}`;\n }\n}\n\n/** Strip markdown formatting so TTS reads clean text. */\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/\\*\\*(.*?)\\*\\*/g, '$1') // bold\n .replace(/[*_~`#]/g, '') // residual markers\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1') // links → label only\n .replace(/\\n{2,}/g, '. ') // paragraph breaks → pause\n .trim();\n}\n\n/**\n * Split text into sentence-level chunks for TTS.\n * Chrome kills a single SpeechSynthesisUtterance after ~15 s, so we\n * speak many short utterances chained sequentially.\n *\n * Protects decimal numbers (e.g. $49.99) from being split at the dot.\n */\nfunction splitIntoChunks(text: string, maxLen = 120): string[] {\n // 1. Protect decimal numbers from being treated as sentence-endings.\n // e.g. \"$49.99\" → \"$49‸99\" (using a placeholder)\n const PLACEHOLDER = '\\u2038'; // ‸ caret\n const safe = text.replace(/(\\d)\\.(\\d)/g, `$1${PLACEHOLDER}$2`);\n\n // 2. Split on sentence / clause punctuation (keep the punctuation).\n // Handles . ! ? । : ; and newlines.\n const parts = safe.match(/[^.!?।:;\\n]+[.!?।:;\\n]+[\\s]*/g);\n const sentences: string[] = parts\n ? parts.map((p) => p.replace(new RegExp(PLACEHOLDER, 'g'), '.'))\n : [text];\n\n // 3. Merge small sentences into chunks ≤ maxLen.\n const chunks: string[] = [];\n let buf = '';\n for (const s of sentences) {\n if (buf.length + s.length > maxLen && buf) {\n chunks.push(buf.trim());\n buf = '';\n }\n buf += s;\n }\n if (buf.trim()) chunks.push(buf.trim());\n\n // 4. Safety: force-split any chunk still over maxLen (rare).\n const result: string[] = [];\n for (const c of chunks) {\n if (c.length <= maxLen) {\n result.push(c);\n } else {\n // Split on comma or space nearest to maxLen.\n let remaining = c;\n while (remaining.length > maxLen) {\n let idx = remaining.lastIndexOf(',', maxLen);\n if (idx < maxLen / 2) idx = remaining.lastIndexOf(' ', maxLen);\n if (idx < 1) idx = maxLen;\n result.push(remaining.slice(0, idx + 1).trim());\n remaining = remaining.slice(idx + 1).trim();\n }\n if (remaining) result.push(remaining);\n }\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Public API types\n// ---------------------------------------------------------------------------\n\nexport interface UseVoiceOptions {\n /** BCP-47 language for STT & TTS (e.g. 'en-US'). */\n lang: string;\n /** Called with the final transcript when the user finishes speaking. */\n onTranscript: (text: string) => void;\n /** Milliseconds of silence before auto-sending (default 1200). */\n silenceMs?: number;\n /** Whether TTS should speak new assistant messages triggered by voice input. */\n autoSpeak?: boolean;\n}\n\nexport interface UseVoiceReturn {\n /** Whether the Web Speech API is available in this browser. */\n isSupported: boolean;\n /** Whether the mic is currently active / recording. */\n isListening: boolean;\n /** Live interim transcript while recording. */\n transcript: string;\n /** Human-readable error, or null. */\n error: string | null;\n /** Start recording. No-op if already listening. */\n start: () => void;\n /** Stop recording (fires onTranscript if there is accumulated text). */\n stop: () => void;\n /** Speak text aloud via TTS. */\n speak: (text: string) => void;\n /** Cancel any ongoing TTS playback. */\n cancelSpeech: () => void;\n /** Whether TTS is currently speaking. */\n isSpeaking: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useVoice({\n lang,\n onTranscript,\n silenceMs = 1200,\n autoSpeak = true,\n}: UseVoiceOptions): UseVoiceReturn {\n // ---- constructor (stable across renders) ----\n const Ctor = useMemo(getRecognitionCtor, []);\n\n // ---- state exposed to consumers ----\n const [isListening, setIsListening] = useState(false);\n const [transcript, setTranscript] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isSpeaking, setIsSpeaking] = useState(false);\n\n // ---- internal refs ----\n const recRef = useRef<SpeechRecognitionInstance | null>(null);\n const finalBuf = useRef(''); // accumulated final fragments\n const silenceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const onTranscriptRef = useRef(onTranscript); // always-current callback\n const langRef = useRef(lang);\n const ttsWarm = useRef(false);\n const mountedRef = useRef(true);\n const keepAliveRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const speakSessionRef = useRef(0); // bumped each speak() call\n\n // Keep refs in sync without causing re-renders.\n onTranscriptRef.current = onTranscript;\n langRef.current = lang;\n\n // ---- TTS warm-up (run once after mount) ----\n useEffect(() => {\n if (ttsWarm.current) return;\n if (typeof window === 'undefined' || !('speechSynthesis' in window)) return;\n ttsWarm.current = true;\n // A zero-length utterance warms up the synth engine so the first real\n // utterance plays without the browser's cold-start pause.\n const u = new SpeechSynthesisUtterance('');\n u.volume = 0;\n window.speechSynthesis.speak(u);\n }, []);\n\n // ---- helpers ----\n const clearSilence = useCallback(() => {\n if (silenceTimer.current) {\n clearTimeout(silenceTimer.current);\n silenceTimer.current = null;\n }\n }, []);\n\n const flushTranscript = useCallback(() => {\n const text = finalBuf.current.trim();\n finalBuf.current = '';\n if (!mountedRef.current) return;\n setTranscript('');\n if (text) onTranscriptRef.current(text);\n }, []);\n\n // ---- SpeechRecognition lifecycle ----\n\n /**\n * Lazily create (or reconfigure) a single SpeechRecognition instance.\n * Reusing the same instance avoids the ~300 ms startup cost of calling\n * `new SpeechRecognition()` each time.\n */\n const getOrCreateRec = useCallback((): SpeechRecognitionInstance | null => {\n if (!Ctor) return null;\n if (recRef.current) {\n // Just update the language — all handlers are already attached.\n recRef.current.lang = langRef.current;\n return recRef.current;\n }\n\n const rec = new Ctor();\n rec.continuous = true; // keep listening until explicitly stopped\n rec.interimResults = true;\n rec.maxAlternatives = 1;\n rec.lang = langRef.current;\n\n rec.onstart = () => {\n if (!mountedRef.current) return;\n setIsListening(true);\n setError(null);\n setTranscript('');\n finalBuf.current = '';\n // Cancel any ongoing TTS so the mic doesn't pick it up.\n if (typeof window !== 'undefined' && 'speechSynthesis' in window) {\n window.speechSynthesis.cancel();\n }\n };\n\n rec.onresult = (ev: SpeechRecognitionResultEvent) => {\n if (!mountedRef.current) return;\n let interim = '';\n for (let i = ev.resultIndex; i < ev.results.length; i++) {\n const seg = ev.results[i];\n const text = seg[0]?.transcript ?? '';\n if (seg.isFinal) {\n finalBuf.current = (finalBuf.current + ' ' + text).trim();\n } else {\n interim += text;\n }\n }\n\n // Show the most relevant text to the user immediately.\n setTranscript(finalBuf.current ? finalBuf.current : interim.trim());\n\n // ---- silence-based auto-send ----\n // Every time we get a result reset the silence timer. When no new\n // results arrive for `silenceMs` we automatically flush.\n clearSilence();\n silenceTimer.current = setTimeout(() => {\n if (!mountedRef.current) return;\n // Stop the recognizer — `onend` will fire but with an empty buffer\n // because we already flushed.\n recRef.current?.stop();\n flushTranscript();\n setIsListening(false);\n }, silenceMs);\n };\n\n rec.onerror = (ev: SpeechRecognitionErrorEvent) => {\n if (!mountedRef.current) return;\n const msg = friendlyError(ev.error);\n if (msg) setError(msg);\n // For fatal errors, stop listening.\n if (['not-allowed', 'service-not-allowed', 'audio-capture'].includes(ev.error)) {\n clearSilence();\n setIsListening(false);\n }\n };\n\n rec.onend = () => {\n if (!mountedRef.current) return;\n clearSilence();\n // Flush anything remaining (e.g. the browser decided to stop early).\n flushTranscript();\n setIsListening(false);\n };\n\n recRef.current = rec;\n return rec;\n }, [Ctor, clearSilence, flushTranscript, silenceMs]);\n\n // ---- public: start / stop ----\n\n const start = useCallback(() => {\n if (isListening) return;\n setError(null);\n const rec = getOrCreateRec();\n if (!rec) {\n setError('Voice input is not supported in this browser.');\n return;\n }\n try {\n rec.start();\n } catch {\n // Already started — ignore.\n }\n }, [isListening, getOrCreateRec]);\n\n const stop = useCallback(() => {\n clearSilence();\n try {\n recRef.current?.stop();\n } catch {\n // Already stopped — ignore.\n }\n }, [clearSilence]);\n\n // ---- public: TTS ----\n\n const clearKeepAlive = useCallback(() => {\n if (keepAliveRef.current) {\n clearInterval(keepAliveRef.current);\n keepAliveRef.current = null;\n }\n }, []);\n\n const speak = useCallback(\n (text: string) => {\n if (typeof window === 'undefined' || !('speechSynthesis' in window)) return;\n if (!autoSpeak) return;\n const clean = stripMarkdown(text);\n if (!clean) return;\n\n // Cancel any previous speech and bump the session id so stale\n // onend callbacks from a cancelled chain don't continue.\n window.speechSynthesis.cancel();\n clearKeepAlive();\n const session = ++speakSessionRef.current;\n\n const chunks = splitIntoChunks(clean);\n let idx = 0;\n\n const speakNext = () => {\n // Abort if a newer speak() call has started or component unmounted.\n if (speakSessionRef.current !== session || !mountedRef.current) {\n clearKeepAlive();\n if (mountedRef.current) setIsSpeaking(false);\n return;\n }\n if (idx >= chunks.length) {\n clearKeepAlive();\n if (mountedRef.current) setIsSpeaking(false);\n return;\n }\n\n const u = new SpeechSynthesisUtterance(chunks[idx]);\n u.lang = langRef.current;\n idx++;\n\n u.onstart = () => {\n // Reset keepalive per-chunk (Chrome pause/resume trick, 5 s).\n clearKeepAlive();\n keepAliveRef.current = setInterval(() => {\n if (window.speechSynthesis.speaking && !window.speechSynthesis.paused) {\n window.speechSynthesis.pause();\n window.speechSynthesis.resume();\n }\n }, 5_000);\n };\n\n u.onend = () => {\n clearKeepAlive();\n speakNext(); // chain to next chunk\n };\n\n u.onerror = () => {\n clearKeepAlive();\n if (mountedRef.current) setIsSpeaking(false);\n };\n\n window.speechSynthesis.speak(u);\n };\n\n if (mountedRef.current) setIsSpeaking(true);\n speakNext();\n },\n [autoSpeak, clearKeepAlive],\n );\n\n const cancelSpeech = useCallback(() => {\n clearKeepAlive();\n if (typeof window !== 'undefined' && 'speechSynthesis' in window) {\n window.speechSynthesis.cancel();\n }\n if (mountedRef.current) setIsSpeaking(false);\n }, [clearKeepAlive]);\n\n // ---- cleanup on unmount ----\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n clearSilence();\n clearKeepAlive();\n recRef.current?.abort();\n recRef.current = null;\n if (typeof window !== 'undefined' && 'speechSynthesis' in window) {\n window.speechSynthesis.cancel();\n }\n };\n }, [clearSilence, clearKeepAlive]);\n\n return {\n isSupported: !!Ctor,\n isListening,\n transcript,\n error,\n start,\n stop,\n speak,\n cancelSpeech,\n isSpeaking,\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {a,c,d,e,f}from'./chunk-UWRZ4ZYG.js';import qe,{useMemo,useReducer,useRef,useState,useEffect,useCallback}from'react';import {z}from'zod';import {createLogger,normalizeWidgetConfig,createMessageId}from'@navsi.ai/shared';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var mt=z.object({type:z.string().min(1).max(50)}).passthrough(),bt=z.object({type:z.literal("auth_success"),sessionId:z.string().max(255),accessToken:z.string().max(4096),refreshToken:z.string().max(4096),expiresAt:z.number(),reconnectToken:z.string().max(255).optional()}).passthrough(),vt=z.object({type:z.literal("token_refreshed"),accessToken:z.string().max(4096),refreshToken:z.string().max(4096),expiresAt:z.number()}).passthrough(),Fe=class{queue=[];maxSize;constructor(e=100){this.maxSize=e;}enqueue(e){this.queue.length>=this.maxSize&&this.queue.shift(),this.queue.push(e);}dequeueAll(){let e=[...this.queue];return this.queue=[],e}get length(){return this.queue.length}clear(){this.queue=[];}},ce=class i{ws=null;config;state="disconnected";logger=createLogger("SDK.WebSocket");reconnectAttempts=0;reconnectTimeout=null;heartbeatInterval=null;lastPongTime=0;messageQueue=new Fe;sessionId=null;refreshToken=null;tokenExpiresAt=0;tokenRefreshTimeout=null;listeners=new Map;constructor(e){this.config={serverUrl:e.serverUrl,apiKey:e.apiKey,autoReconnect:e.autoReconnect??true,maxReconnectAttempts:e.maxReconnectAttempts??10,reconnectDelay:e.reconnectDelay??1e3,heartbeatInterval:e.heartbeatInterval??3e4,debug:e.debug??false},this.logger=createLogger("SDK.WebSocket",{enabled:this.config.debug,level:"debug"});}connect(){if(this.state==="connecting"||this.state==="connected"){this.log("Already connected or connecting");return}this.setState("connecting"),this.createWebSocket();}disconnect(){this.closeSocket(),this.setState("disconnected"),this.log("Disconnected");}destroy(){this.cleanup(),this.setState("disconnected"),this.log("Destroyed");}send(e){this.state==="connected"&&this.ws?.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify(e)),this.log("Sent message:",e.type,Qe(e))):(this.messageQueue.enqueue(e),this.log("Queued message (offline):",e.type,Qe(e)));}getState(){return this.state}getSessionId(){return this.sessionId}isConnected(){return this.state==="connected"}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.listeners.get(e)?.delete(t);}}emit(e,t){this.listeners.get(e)?.forEach(n=>{try{n(t);}catch(r){this.logger.error(`Error in ${e} listener`,r);}});}createWebSocket(){try{let e=new URL(this.config.serverUrl);this.sessionId&&e.searchParams.set("sessionId",this.sessionId);let t=e.toString();this.ws=new WebSocket(t),this.ws.onopen=this.handleOpen.bind(this),this.ws.onmessage=this.handleMessage.bind(this),this.ws.onclose=this.handleClose.bind(this),this.ws.onerror=this.handleError.bind(this);}catch(e){this.logger.error("Failed to create WebSocket",e),this.handleConnectionFailure();}}handleOpen(){this.log("WebSocket connected, sending auth message..."),this.ws?.send(JSON.stringify({type:"auth",apiKey:this.config.apiKey,sessionId:this.sessionId}));}handleMessage(e){try{let t=JSON.parse(e.data),n=mt.safeParse(t);if(!n.success){this.logger.warn("Invalid server message shape",n.error.issues);return}let r=t;switch(this.log("Received message:",r.type),r.type){case "connected":this.handleConnected();break;case "auth_success":{let o=bt.safeParse(r);if(!o.success){this.logger.warn("Invalid auth_success message",o.error.issues);return}this.handleAuthSuccess(o.data);break}case "auth_error":this.handleAuthError(r);break;case "pong":this.handlePong(r);break;case "token_refreshed":{let o=vt.safeParse(r);if(!o.success){this.logger.warn("Invalid token_refreshed message",o.error.issues);return}this.handleTokenRefreshed(o.data);break}default:this.emit("message",r);}}catch(t){this.logger.warn("Failed to parse message",t);}}static NON_RETRIABLE_CLOSE_CODES=new Set([1008,4001,4003,4004,4010]);handleClose(e){this.log("WebSocket closed:",e.code,e.reason),this.stopHeartbeat(),this.state!=="disconnected"&&(this.emit("disconnected",{reason:e.reason,code:e.code}),this.config.autoReconnect&&!i.NON_RETRIABLE_CLOSE_CODES.has(e.code)?this.scheduleReconnect():this.setState("disconnected"));}handleError(e){this.logger.error("WebSocket error",e),this.emit("error",{error:new Error("WebSocket error")});}handleConnected(){this.log("Server connection acknowledged");}handleAuthSuccess(e){this.sessionId=e.sessionId,this.refreshToken=e.refreshToken,this.tokenExpiresAt=e.expiresAt,this.reconnectAttempts=0,this.setState("connected"),this.startHeartbeat(),this.scheduleTokenRefresh(),this.flushMessageQueue(),this.emit("authenticated",{sessionId:e.sessionId,expiresAt:e.expiresAt}),this.emit("connected",{sessionId:e.sessionId}),this.log("Authenticated successfully, session:",e.sessionId);}handleAuthError(e){this.logger.warn("Authentication failed",e.error),this.emit("error",{error:new Error(e.error),code:e.code}),this.disconnect();}scheduleTokenRefresh(){this.tokenRefreshTimeout&&clearTimeout(this.tokenRefreshTimeout);let e=Math.max(0,this.tokenExpiresAt-Date.now()-300*1e3);this.tokenRefreshTimeout=setTimeout(()=>{this.refreshAccessToken();},e),this.log("Token refresh scheduled in",Math.round(e/1e3),"seconds");}refreshAccessToken(){!this.refreshToken||this.state!=="connected"||(this.log("Refreshing token..."),this.ws?.send(JSON.stringify({type:"token_refresh",refreshToken:this.refreshToken})));}handleTokenRefreshed(e){this.refreshToken=e.refreshToken,this.tokenExpiresAt=e.expiresAt,this.scheduleTokenRefresh(),this.emit("token_refreshed",{expiresAt:e.expiresAt}),this.log("Token refreshed successfully");}startHeartbeat(){this.stopHeartbeat(),this.lastPongTime=Date.now(),this.heartbeatInterval=setInterval(()=>{if(this.state==="connected"){if(Date.now()-this.lastPongTime>this.config.heartbeatInterval*2){this.logger.warn("Heartbeat timeout, reconnecting..."),this.ws?.close();return}this.ws?.send(JSON.stringify({type:"ping",timestamp:Date.now()})),this.log("Sent ping");}},this.config.heartbeatInterval);}stopHeartbeat(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null);}handlePong(e){this.lastPongTime=Date.now();let t=Date.now()-e.timestamp;this.log("Received pong, latency:",t,"ms");}scheduleReconnect(){if(this.reconnectAttempts>=this.config.maxReconnectAttempts){this.handleConnectionFailure();return}this.setState("reconnecting"),this.reconnectAttempts++;let e=Math.min(this.config.reconnectDelay*Math.pow(2,this.reconnectAttempts-1),3e4);this.log(`Reconnecting in ${e}ms (attempt ${this.reconnectAttempts}/${this.config.maxReconnectAttempts})`),this.emit("reconnecting",{attempt:this.reconnectAttempts,maxAttempts:this.config.maxReconnectAttempts}),this.reconnectTimeout=setTimeout(()=>{this.createWebSocket();},e);}handleConnectionFailure(){this.setState("failed"),this.emit("reconnect_failed",{reason:"Max reconnection attempts reached"}),this.logger.error("Connection failed - max reconnection attempts reached");}flushMessageQueue(){let e=this.messageQueue.dequeueAll();e.length>0&&(this.log(`Flushing ${e.length} queued messages`),e.forEach(t=>this.send(t)));}setState(e){this.state!==e&&(this.log("State:",this.state,"->",e),this.state=e);}closeSocket(){if(this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null),this.tokenRefreshTimeout&&(clearTimeout(this.tokenRefreshTimeout),this.tokenRefreshTimeout=null),this.stopHeartbeat(),this.ws){let e=this.ws;if(e.onopen=null,e.onmessage=null,e.onclose=null,e.onerror=null,this.ws=null,e.readyState===WebSocket.CONNECTING||e.readyState===WebSocket.OPEN)try{e.close(1e3,"Client disconnect");}catch{}}}cleanup(){this.closeSocket(),this.listeners.clear();}log(...e){this.logger.debug(...e);}};function Qe(i){switch(i.type){case "message":return {messageId:i.messageId,mode:i.mode,length:i.content.length,route:i.context?.route};case "context":return {route:i.context?.route,actions:i.context?.actions?.length??0,headings:i.context?.content?.headings?.length??0};case "action_result":return {actionId:i.actionId,success:i.success,commandId:i.commandId};case "server_action_request":return {actionId:i.actionId,requestId:i.requestId};case "auth":return {hasSessionId:!!i.sessionId};case "token_refresh":return {};case "ping":return {timestamp:i.timestamp};default:return {}}}function en(i){return new ce(i)}function Ze(i="/"){let e=i,t=new Set;return {navigate(n){e=n,t.forEach(r=>r(n));},getCurrentPath(){return e},onRouteChange(n){return t.add(n),()=>t.delete(n)},async waitForRoute(n,r=1e4){return new Promise(o=>{if(e===n){o(true);return}let s=this.onRouteChange(a=>{a===n&&(s(),o(true));});setTimeout(()=>{s(),o(e===n);},r);})}}}var le=class{adapter;config;scanCallback=null;logger=createLogger("SDK.Navigation");constructor(e,t={}){this.adapter=e,this.config={domStabilityDelay:t.domStabilityDelay??300,domStabilityTimeout:t.domStabilityTimeout??5e3,debug:t.debug??false,onDOMStable:t.onDOMStable},this.logger=createLogger("SDK.Navigation",{enabled:this.config.debug,level:"debug"});}setScanner(e){this.scanCallback=e;}getCurrentRoute(){return this.adapter.getCurrentPath()}async navigateTo(e,t){if(this.adapter.getCurrentPath()===e)return this.log("Already on route:",e),true;this.log("Navigating to:",e),this.adapter.navigate(e);let r=await this.adapter.waitForRoute(e,t);return r||this.log("Navigation timeout for route:",e),r}async executeNavigation(e){if(!await this.navigateTo(e))return this.log("Navigation failed to:",e),null;if(await this.waitForDOMStable(),this.scanCallback){let n=await this.scanCallback();return this.log("Rescanned context on route:",e),n}return null}async waitForDOMStable(){this.logger.debug("Waiting for DOM stability",{delayMs:this.config.domStabilityDelay,timeoutMs:this.config.domStabilityTimeout});let e=()=>{this.config.onDOMStable?.();};return new Promise(t=>{let n=false,r=()=>{n||(n=true,e(),t());};if(typeof document>"u"||typeof MutationObserver>"u"){r();return}let o,s,a=Date.now(),c=()=>{u.disconnect(),clearTimeout(o),clearTimeout(s);},u=new MutationObserver(()=>{if(clearTimeout(o),Date.now()-a>=this.config.domStabilityTimeout){c(),this.log("DOM stability timeout reached"),r();return}o=setTimeout(()=>{c(),this.log("DOM is stable"),r();},this.config.domStabilityDelay);});u.observe(document.body,{childList:true,subtree:true,attributes:false}),o=setTimeout(()=>{c(),this.log("DOM is stable (no initial mutations)"),r();},this.config.domStabilityDelay),s=setTimeout(()=>{c(),this.log("DOM stability max timeout reached"),r();},this.config.domStabilityTimeout);})}onRouteChange(e){return this.adapter.onRouteChange(e)}log(...e){this.logger.debug(...e);}};function on(i,e){return new le(i,e)}var yt=["button:not([disabled])","a[href]:not([disabled])",'input:not([type="hidden"]):not([disabled])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[contenteditable="plaintext-only"]','[role="textbox"]','[role="searchbox"]','[role="combobox"]','[role="checkbox"]','[role="switch"]','[role="radio"]','[role="button"]:not([disabled])','[role="link"]','[role="menuitem"]','[role="tab"]',"[onclick]","[data-chatbot-action]"],xt=["[data-chatbot-ignore]",'[aria-hidden="true"]',"[hidden]",".chatbot-widget",".navsi-chatbot-container",'[type="password"]','[autocomplete*="cc-"]'];function Et(i){let e=i.getAttribute("data-chatbot-action");if(e)return `[data-chatbot-action="${e}"]`;if(i.id)return `#${CSS.escape(i.id)}`;let t=i.getAttribute("data-testid");if(t)return `[data-testid="${CSS.escape(t)}"]`;let n=i.getAttribute("aria-label");if(n){let o=`[aria-label="${CSS.escape(n)}"]`;if(document.querySelectorAll(o).length===1)return o}let r=i.getAttribute?.("name");if(r&&/^(input|select|textarea|button)$/i.test(i.tagName)){let o=`${i.tagName.toLowerCase()}[name="${CSS.escape(r)}"]`;if(document.querySelectorAll(o).length===1)return o}if(i.className&&typeof i.className=="string"){let o=i.className.split(/\s+/).filter(Boolean).slice(0,3);if(o.length>0){let s=`${i.tagName.toLowerCase()}.${o.map(c=>CSS.escape(c)).join(".")}`;if(document.querySelectorAll(s).length===1)return s}}return St(i)}function St(i){let e=[],t=i;for(;t&&t!==document.body;){let n=t.tagName.toLowerCase();if(t.id){n=`#${CSS.escape(t.id)}`,e.unshift(n);break}let r=t.parentElement;if(r){let o=t.tagName,s=r.children,a=[];for(let c=0;c<s.length;c++)s[c].tagName===o&&a.push(s[c]);if(a.length>1){let c=a.indexOf(t)+1;n+=`:nth-of-type(${c})`;}}e.unshift(n),t=r;}return e.join(" > ")}function wt(i){let e=window.getComputedStyle(i);if(e.display==="none"||e.visibility==="hidden"||e.opacity==="0")return false;let t=i.getBoundingClientRect();return !(t.width===0&&t.height===0||i.closest('[aria-hidden="true"]'))}function Ct(i){for(let e of xt)if(i.matches(e)||i.closest(e))return true;return false}function Rt(i){let e=i.tagName.toLowerCase(),t=i.getAttribute("role")?.toLowerCase();if(e==="input"){let n=i.type;return n==="checkbox"||n==="radio"?"click":"type"}return e==="textarea"?"type":e==="select"?"select":t==="textbox"||t==="searchbox"?"type":"click"}function At(i){let e=i.getAttribute("data-chatbot-action");if(e)return e.replace(/-/g," ");let t=i.getAttribute("aria-label");if(t)return t;let n=i.getAttribute("aria-labelledby");if(n){let c=n.split(/\s+/).map(u=>document.getElementById(u)?.textContent?.trim()).filter(Boolean).join(" ");if(c)return c}let r=i.getAttribute("title");if(r)return r;let o=i.textContent?.trim();if(o&&o.length<50)return o;let s=i.getAttribute("placeholder");if(s)return s;let a=i.getAttribute("name");if(a)return a.replace(/[-_]/g," ");if(i.id){let c=document.querySelector(`label[for="${i.id}"]`);if(c?.textContent)return c.textContent.trim()}return i.tagName.toLowerCase()}var Tt=["tr",'[role="row"]',"article",'[role="listitem"]',"section",'[role="group"]',"main",'[role="region"]'],nt=120;function kt(i){let e=i,t=0,n=8;for(;e&&e!==document.body&&t<n;){for(let r of Tt)try{if(e.matches(r)){let o=e.textContent?.trim().replace(/\s+/g," ");if(o&&o.length>0)return o.length>nt?o.slice(0,nt)+"\u2026":o;break}}catch{}e=e.parentElement,t++;}}function Mt(i){let e=i.parentElement,t=0,n=5;for(;e&&t<n;){let r=e.querySelector("h1, h2, h3, h4, h5, h6");if(r?.textContent)return r.textContent.trim();let o=e.previousElementSibling;for(;o;){if(/^H[1-6]$/.test(o.tagName))return o.textContent?.trim();o=o.previousElementSibling;}e=e.parentElement,t++;}}var Te=class{config;mutationObserver=null;scanTimeout=null;onChangeCallback=null;logger=createLogger("SDK.Scanner");constructor(e={}){this.config={root:e.root??(typeof document<"u"?document.body:null),debug:e.debug??false,maxActions:e.maxActions??100,debounceMs:e.debounceMs??300},this.logger=createLogger("SDK.Scanner",{enabled:this.config.debug,level:"debug"});}scan(){if(typeof document>"u")return [];let e=this.config.root??document.body,t=[],n=typeof window<"u"?window.location.pathname:"/",r=yt.join(", "),o=this.collectInteractiveElements(e,r);this.log(`Found ${o.length} potential interactive elements`);for(let s of o){if(t.length>=this.config.maxActions)break;if(Ct(s)||!wt(s))continue;let a=this.createElement(s,n);a&&t.push(a);}return this.log(`Discovered ${t.length} actions`),t}createElement(e,t){try{let n=Et(e),r=At(e),o=Rt(e),s=Mt(e),u={id:`action_${btoa(unescape(encodeURIComponent(n))).replace(/[^a-zA-Z0-9]/g,"").slice(0,16)}`,type:o,selector:n,label:r,route:t,isAutoDiscovered:!0,priority:e.hasAttribute("data-chatbot-action")?10:1},h=kt(e);return (s||h)&&(u.metadata={...s?{context:s}:{},...h?{containerText:h}:{}}),u}catch(n){return this.log("Error creating action:",n),null}}collectInteractiveElements(e,t){let n=new Set,r=[e];for(;r.length>0;){let o=r.shift();if(!o)break;let a=(o).querySelectorAll(t);for(let h of a)n.add(h);let u=(o).querySelectorAll("*");for(let h of u){let E=h.shadowRoot;E&&r.push(E);}}return Array.from(n)}observe(e){typeof MutationObserver>"u"||(this.disconnect(),this.onChangeCallback=e,this.mutationObserver=new MutationObserver(()=>{this.debouncedScan();}),this.mutationObserver.observe(this.config.root??document.body,{childList:true,subtree:true,attributes:true,attributeFilter:["disabled","hidden","aria-hidden"]}));}disconnect(){this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.scanTimeout&&(clearTimeout(this.scanTimeout),this.scanTimeout=null);}debouncedScan(){this.scanTimeout&&clearTimeout(this.scanTimeout),this.scanTimeout=setTimeout(()=>{let e=this.scan();this.onChangeCallback?.(e);},this.config.debounceMs);}log(...e){this.logger.debug(...e);}};var ke=class{actionsByRoute=new Map;serverActions=new Map;manualActions=new Map;debug;logger=createLogger("SDK.Registry");constructor(e={}){this.debug=e.debug??false,this.logger=createLogger("SDK.Registry",{enabled:this.debug,level:"debug"});}registerDiscoveredActions(e,t){this.actionsByRoute.has(e)||this.actionsByRoute.set(e,new Map);let n=this.actionsByRoute.get(e);for(let[r,o]of n)o.isAutoDiscovered&&n.delete(r);for(let r of t){let o=this.manualActions.get(r.id);o?n.set(r.id,{...r,...o}):n.set(r.id,r);}this.log(`Registered ${t.length} discovered actions for route: ${e}`);}registerManualAction(e){this.manualActions.set(e.id,e);let t=this.actionsByRoute.get(e.route);if(t?.has(e.id)){let n=t.get(e.id);t.set(e.id,{...n,...e,isAutoDiscovered:false});}this.log(`Registered manual action: ${e.id}`);}getActionsForRoute(e){let t=this.actionsByRoute.get(e);return t?Array.from(t.values()).sort((n,r)=>(r.priority??0)-(n.priority??0)):[]}findActionById(e){for(let t of this.actionsByRoute.values()){let n=t.get(e);if(n)return n}return null}findActionBySelector(e,t){let n=this.actionsByRoute.get(e);if(!n)return null;for(let r of n.values())if(r.selector===t)return r;return null}findActionByLabel(e,t,n){let r=this.actionsByRoute.get(e);if(!r)return null;let o=t.toLowerCase().trim(),s=n?.toLowerCase().trim(),a=c=>{if(!s)return true;let u=c.metadata?.containerText?.toLowerCase(),h=c.metadata?.context?.toLowerCase();return (u?.includes(s)??false)||(h?.includes(s)??false)};if(s){for(let c of r.values())if(c.label.toLowerCase()===o&&a(c))return c;for(let c of r.values())if(c.label.toLowerCase().includes(o)&&a(c))return c}for(let c of r.values())if(c.label.toLowerCase()===o)return c;for(let c of r.values())if(c.label.toLowerCase().includes(o))return c;return null}clearRoute(e){this.actionsByRoute.delete(e);}clearAll(){this.actionsByRoute.clear();}registerServerAction(e){this.serverActions.set(e.id,e),this.log(`Registered server action: ${e.id}`);}getServerActions(){return Array.from(this.serverActions.values())}findServerActionById(e){return this.serverActions.get(e)??null}findServerActionByName(e){let t=e.toLowerCase().trim();for(let n of this.serverActions.values())if(n.name.toLowerCase()===t)return n;for(let n of this.serverActions.values())if(n.name.toLowerCase().includes(t))return n;return null}removeServerAction(e){this.serverActions.delete(e);}getStats(){let e=0;for(let t of this.actionsByRoute.values())e+=t.size;return {routes:this.actionsByRoute.size,actions:e,serverActions:this.serverActions.size}}log(...e){this.logger.debug(...e);}};function Nt(i){return i.replace(/\s+/g," ").trim()}function It(){if(typeof document>"u")return [];let i=["chatbot","ai assistant","ask mode","navigate mode","navsi","intelligent agent"],e=[],t=document.querySelectorAll("h1, h2, h3, h4, h5, h6");for(let n of t){if(n.closest(".chatbot-widget")||n.closest(".navsi-chatbot-container"))continue;let r=n.textContent?.trim();if(r&&r.length<200){let o=r.toLowerCase();i.some(a=>o.includes(a))||e.push(r);}}return e.slice(0,20)}function Dt(i){if(typeof document>"u")return "";let e=document.querySelector("main")??document.querySelector('[role="main"]')??document.querySelector("article")??document.querySelector(".content")??document.body,t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,{acceptNode:o=>{let s=o.parentElement;if(!s)return NodeFilter.FILTER_REJECT;let a=s.tagName.toLowerCase();return ["script","style","noscript"].includes(a)||s.closest(".chatbot-widget")||s.closest(".navsi-chatbot-container")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),n="",r;for(;(r=t.nextNode())&&n.length<i;){let o=r.textContent?.trim();o&&o.length>0&&(n+=o+" ");}return Nt(n).slice(0,i)}function Ot(){if(typeof document>"u")return [];let i=[],e=document.querySelectorAll("form");for(let t of e){if(t.closest(".chatbot-widget")||t.closest(".navsi-chatbot-container"))continue;let n=[],r=t.querySelectorAll("input, select, textarea");for(let o of r){let s=o;if(s.type==="hidden")continue;let a;s.id&&(a=document.querySelector(`label[for="${s.id}"]`)?.textContent?.trim()),!a&&s.getAttribute("aria-label")&&(a=s.getAttribute("aria-label")??void 0),n.push({name:s.name||s.id||"",type:s.type||s.tagName.toLowerCase(),label:a,placeholder:"placeholder"in s?s.placeholder:void 0,required:s.required});}n.length>0&&i.push({id:t.id||`form_${i.length}`,name:t.name||void 0,action:t.action?(()=>{try{return new URL(t.action).pathname}catch{return}})():void 0,method:t.method||void 0,fields:n});}return i.slice(0,10)}function _t(){return typeof document>"u"?void 0:document.querySelector('meta[name="description"]')?.getAttribute("content")??void 0}var Me=class{config;logger=createLogger("SDK.Context");constructor(e={}){this.config={maxContentLength:e.maxContentLength??2e3,maxActions:e.maxActions??50,debug:e.debug??false},this.logger=createLogger("SDK.Context",{enabled:this.config.debug,level:"debug"});}build(e,t,n){let r=n??(typeof window<"u"?window.location.pathname:"/"),o=typeof document<"u"?document.title:"",s={headings:It(),mainContent:Dt(this.config.maxContentLength),forms:Ot(),metaDescription:_t()},a=e.slice(0,this.config.maxActions),c={route:r,title:o,actions:a,serverActions:t,content:s,timestamp:Date.now()};return this.log("Built page context:",{route:c.route,title:c.title,actions:c.actions.length,serverActions:c.serverActions.length,headings:c.content.headings.length,forms:c.content.forms.length}),c}buildMinimal(e,t,n){return {route:n??(typeof window<"u"?window.location.pathname:"/"),title:typeof document<"u"?document.title:"",actions:e.slice(0,this.config.maxActions),serverActions:t,content:{headings:[],mainContent:"",forms:[]},timestamp:Date.now()}}log(...e){this.logger.debug(...e);}};function ge(i,e){let t=e?.preferVisible??false,n=[document],r=null;for(;n.length>0;){let o=n.shift(),s=o.querySelector(i);if(s){if(!t||X(s))return s;r||(r=s);}let a=o instanceof Document?o.body??o.documentElement:o;if(!a)continue;let c=a.querySelectorAll("*");for(let u of c){let h=u.shadowRoot;h&&n.push(h);}}return t?r:null}async function ue(i,e,t=true){let r=o=>o?!t||X(o):false;return new Promise(o=>{let s=ge(i,{preferVisible:t});if(r(s)){o(s);return}let a=false,c=null,u=null,h=()=>{a=true,c&&clearInterval(c),u&&clearTimeout(u),E.disconnect();},E=new MutationObserver(()=>{if(a)return;let S=ge(i,{preferVisible:t});r(S)&&(h(),o(S));});E.observe(document.body,{childList:true,subtree:true}),c=setInterval(()=>{if(a)return;let S=ge(i,{preferVisible:t});r(S)&&(h(),o(S));},100),u=setTimeout(()=>{if(a)return;h();let S=ge(i,{preferVisible:t});o(r(S)?S:null);},e);})}function X(i){let e=window.getComputedStyle(i);if(e.display==="none"||e.visibility==="hidden"||e.opacity==="0")return false;let t=i.getBoundingClientRect();if(t.width===0&&t.height===0)return false;let n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,o=t.right>0&&t.left<n,s=t.bottom>0&&t.top<r;return o&&s}function Lt(i){let e=i.getBoundingClientRect();return {x:e.left+e.width/2,y:e.top+e.height/2}}function Ue(i,e){let t=i instanceof HTMLInputElement?HTMLInputElement.prototype:HTMLTextAreaElement.prototype,n=Object.getOwnPropertyDescriptor(t,"value")?.set;n?n.call(i,e):i.value=e;}function Ne(i){i.scrollIntoView({behavior:"smooth",block:"center",inline:"center"});}function de(i,e=500){let t=i,n=t.style.outline,r=t.style.transition;t.style.transition="outline 0.2s ease",t.style.outline="3px solid #6366f1",setTimeout(()=>{t.style.outline=n,t.style.transition=r;},e);}async function Pt(i,e,t){i.focus(),Ue(i,""),i.dispatchEvent(new Event("input",{bubbles:true}));for(let n of e){try{typeof InputEvent<"u"&&i.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,data:n,inputType:"insertText"}));}catch{}let r=(i.value??"")+n;Ue(i,r),i.dispatchEvent(new Event("input",{bubbles:true})),i.dispatchEvent(new KeyboardEvent("keydown",{key:n,bubbles:true})),i.dispatchEvent(new KeyboardEvent("keypress",{key:n,bubbles:true})),i.dispatchEvent(new KeyboardEvent("keyup",{key:n,bubbles:true})),t>0&&await new Promise(o=>setTimeout(o,t));}i.dispatchEvent(new Event("change",{bubbles:true}));}async function $t(i,e,t){i.focus(),i.textContent="",i.dispatchEvent(new Event("input",{bubbles:true}));for(let n of e){try{typeof InputEvent<"u"&&i.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,data:n,inputType:"insertText"}));}catch{}i.textContent=(i.textContent??"")+n,i.dispatchEvent(new Event("input",{bubbles:true})),i.dispatchEvent(new KeyboardEvent("keydown",{key:n,bubbles:true})),i.dispatchEvent(new KeyboardEvent("keypress",{key:n,bubbles:true})),i.dispatchEvent(new KeyboardEvent("keyup",{key:n,bubbles:true})),t>0&&await new Promise(r=>setTimeout(r,t));}i.dispatchEvent(new Event("change",{bubbles:true}));}function P(i){let e=i.getBoundingClientRect(),t=i.tagName.toLowerCase(),n={};if(i instanceof HTMLElement)for(let r of Array.from(i.attributes))(r.name.startsWith("data-")||r.name==="aria-label"||r.name==="name"||r.name==="id")&&(n[r.name]=r.value);return {tagName:t,text:(i.textContent??"").trim().slice(0,80),rect:{x:e.x,y:e.y,width:e.width,height:e.height},attributes:n}}var Ie=class i{config;logger=createLogger("SDK.Executor");constructor(e={}){this.config={elementTimeout:e.elementTimeout??6e3,typeDelay:e.typeDelay??30,scrollIntoView:e.scrollIntoView??true,highlightOnInteract:e.highlightOnInteract??true,debug:e.debug??false},this.logger=createLogger("SDK.Executor",{enabled:this.config.debug,level:"debug"});}static RETRY_DELAY_MS=600;static MAX_RETRIES=2;async click(e){let t=Date.now(),n=async()=>{let o=await ue(e,this.config.elementTimeout,true);if(!o)return this.createResult(e,"click",t,false,"Element not found","ELEMENT_NOT_FOUND");if(this.config.scrollIntoView&&!X(o)&&(Ne(o),await new Promise(h=>setTimeout(h,100))),this.config.highlightOnInteract&&de(o),!X(o))return this.createResult(e,"click",t,false,"Element is not visible","NOT_VISIBLE",P(o));let s=o;if(s.disabled===true||s.getAttribute("aria-disabled")==="true")return this.createResult(e,"click",t,false,"Element is disabled","DISABLED",P(o));s.focus();let{x:c,y:u}=Lt(o);try{typeof PointerEvent<"u"&&(o.dispatchEvent(new PointerEvent("pointerover",{bubbles:!0,cancelable:!0,clientX:c,clientY:u})),o.dispatchEvent(new PointerEvent("pointerenter",{bubbles:!0,cancelable:!0,clientX:c,clientY:u})),o.dispatchEvent(new PointerEvent("pointermove",{bubbles:!0,cancelable:!0,clientX:c,clientY:u})));}catch{}o.dispatchEvent(new MouseEvent("mouseover",{bubbles:true,cancelable:true,clientX:c,clientY:u})),o.dispatchEvent(new MouseEvent("mouseenter",{bubbles:true,cancelable:true,clientX:c,clientY:u})),o.dispatchEvent(new MouseEvent("mousemove",{bubbles:true,cancelable:true,clientX:c,clientY:u}));try{typeof PointerEvent<"u"&&(o.dispatchEvent(new PointerEvent("pointerdown",{bubbles:!0,cancelable:!0,button:0,clientX:c,clientY:u})),o.dispatchEvent(new PointerEvent("pointerup",{bubbles:!0,cancelable:!0,button:0,clientX:c,clientY:u})));}catch{}return o.dispatchEvent(new MouseEvent("mousedown",{bubbles:true,cancelable:true,clientX:c,clientY:u})),o.dispatchEvent(new MouseEvent("mouseup",{bubbles:true,cancelable:true,clientX:c,clientY:u})),o.dispatchEvent(new MouseEvent("click",{bubbles:true,cancelable:true,clientX:c,clientY:u})),s.click(),this.log("Clicked:",e),this.createResult(e,"click",t,true,void 0,void 0,P(o))};return (async()=>{let o=null;for(let s=0;s<=i.MAX_RETRIES;s++){s>0&&(this.log(`Click retry ${s}/${i.MAX_RETRIES} for:`,e),await new Promise(a=>setTimeout(a,i.RETRY_DELAY_MS*s)));try{if(o=await n(),o.success)return o}catch(a){o=this.createResult(e,"click",t,false,String(a),"RUNTIME_ERROR");}}return o})()}async type(e,t,n=true){let r=Date.now(),o=async()=>{let a=await ue(e,this.config.elementTimeout,true);if(!a)return this.createResult(e,"type",r,false,"Element not found","ELEMENT_NOT_FOUND");if(!this.isTypeable(a))return this.createResult(e,"type",r,false,"Element is not typeable","TYPE_MISMATCH",P(a));this.config.scrollIntoView&&!X(a)&&(Ne(a),await new Promise(u=>setTimeout(u,100))),this.config.highlightOnInteract&&de(a);let c=P(a);if(!X(a))return this.createResult(e,"type",r,false,"Element is not visible","NOT_VISIBLE",c);if(a instanceof HTMLInputElement||a instanceof HTMLTextAreaElement){let u=a;if(u.disabled||u.getAttribute("aria-disabled")==="true")return this.createResult(e,"type",r,false,"Element is disabled","DISABLED",c);n?await Pt(u,t,this.config.typeDelay):(u.focus(),Ue(u,(u.value??"")+t),u.dispatchEvent(new Event("input",{bubbles:true})),u.dispatchEvent(new Event("change",{bubbles:true})));}else if(a instanceof HTMLElement&&a.isContentEditable){if(a.getAttribute("aria-disabled")==="true")return this.createResult(e,"type",r,false,"Element is disabled","DISABLED",c);await $t(a,t,this.config.typeDelay);}else return this.createResult(e,"type",r,false,"Element is not a supported type target","TYPE_MISMATCH",c);return this.log("Typed into:",e,"text:",t.slice(0,20)+(t.length>20?"...":"")),this.createResult(e,"type",r,true,void 0,void 0,{...c,textLength:t.length})};return (async()=>{let a=null;for(let c=0;c<=i.MAX_RETRIES;c++){c>0&&(this.log(`Type retry ${c}/${i.MAX_RETRIES} for:`,e),await new Promise(u=>setTimeout(u,i.RETRY_DELAY_MS*c)));try{if(a=await o(),a.success)return a}catch(u){a=this.createResult(e,"type",r,false,String(u),"RUNTIME_ERROR");}}return a})()}async select(e,t){let n=Date.now(),r=async()=>{let s=await ue(e,this.config.elementTimeout,true);if(!s)return this.createResult(e,"select",n,false,"Element not found","ELEMENT_NOT_FOUND");if(s.tagName.toLowerCase()!=="select")return this.createResult(e,"select",n,false,"Element is not a select","TYPE_MISMATCH",P(s));if(this.config.scrollIntoView&&!X(s)&&(Ne(s),await new Promise(E=>setTimeout(E,100))),this.config.highlightOnInteract&&de(s),!X(s))return this.createResult(e,"select",n,false,"Element is not visible","NOT_VISIBLE",P(s));let a=s;if(a.disabled||a.getAttribute("aria-disabled")==="true")return this.createResult(e,"select",n,false,"Element is disabled","DISABLED",P(s));let c=false,u="";for(let E of a.options)if(E.value===t||E.textContent?.toLowerCase().includes(t.toLowerCase())){u=E.value,c=true;break}if(!c)return this.createResult(e,"select",n,false,`Option not found: ${t}`,"OPTION_NOT_FOUND",{...P(s),attemptedValue:t});let h=Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,"value")?.set;return h?h.call(a,u):a.value=u,a.dispatchEvent(new Event("input",{bubbles:true})),a.dispatchEvent(new Event("change",{bubbles:true})),this.log("Selected:",e,"value:",t),this.createResult(e,"select",n,true,void 0,void 0,{...P(s),selectedValue:t})};return (async()=>{let s=null;for(let a=0;a<=i.MAX_RETRIES;a++){a>0&&(this.log(`Select retry ${a}/${i.MAX_RETRIES} for:`,e),await new Promise(c=>setTimeout(c,i.RETRY_DELAY_MS*a)));try{if(s=await r(),s.success)return s}catch(c){s=this.createResult(e,"select",n,false,String(c),"RUNTIME_ERROR");}}return s})()}async scroll(e){let t=Date.now(),n=typeof e=="string"?e:`${e.x},${e.y}`;try{if(typeof e=="string"){let r=await ue(e,this.config.elementTimeout,!1);if(!r)return this.createResult(n,"scroll",t,!1,"Element not found","ELEMENT_NOT_FOUND");this.config.highlightOnInteract&&de(r),Ne(r);}else window.scrollTo({left:e.x,top:e.y,behavior:"smooth"});return this.log("Scrolled to:",e),this.createResult(n,"scroll",t,!0,void 0,void 0,typeof e=="string"?(()=>{let r=ge(e);return r?P(r):{selector:e}})():{position:e})}catch(r){return this.createResult(n,"scroll",t,false,String(r),"RUNTIME_ERROR")}}async submit(e){let t=Date.now();try{let n=await ue(e,this.config.elementTimeout,!0);if(!n)return this.createResult(e,"submit",t,!1,"Element not found","ELEMENT_NOT_FOUND");let r=n.tagName.toLowerCase()==="form"?n:n.closest("form");if(!r){let s=n.querySelector('button[type="submit"], input[type="submit"]');return s?this.click(this.generateSelector(s)):this.createResult(e,"submit",t,!1,"No form found","NO_FORM",P(n))}this.config.highlightOnInteract&&de(r);let o=r.querySelector('button[type="submit"], input[type="submit"]');if(typeof r.requestSubmit=="function")r.requestSubmit(o??void 0);else {let s=new Event("submit",{bubbles:!0,cancelable:!0});r.dispatchEvent(s)&&r.submit();}return this.log("Submitted form:",e),this.createResult(e,"submit",t,!0,void 0,void 0,P(r))}catch(n){return this.createResult(e,"submit",t,false,String(n),"RUNTIME_ERROR")}}isTypeable(e){let t=e.tagName.toLowerCase();if(t==="input"){let n=e.type;return ["text","email","password","search","tel","url","number"].includes(n)}return !!(t==="textarea"||e.hasAttribute("contenteditable"))}generateSelector(e){if(e.id)return `#${e.id}`;let t=e.getAttribute("data-testid");return t?`[data-testid="${t}"]`:e.tagName.toLowerCase()}createResult(e,t,n,r,o,s,a){return r||this.logger.warn("Action failed",{action:t,selector:e,error:o,errorCode:s,metadata:a}),{success:r,selector:e,action:t,duration:Date.now()-n,errorCode:s,error:o,metadata:a}}log(...e){this.logger.debug(...e);}};var De=class{config;executor;navController;registry;logger=createLogger("SDK.Processor");isExecuting=false;shouldAbort=false;listeners=new Map;serverActionHandler=null;constructor(e,t,n,r={}){this.executor=e,this.navController=t,this.registry=n,this.config={commandDelay:r.commandDelay??300,commandTimeout:r.commandTimeout??3e4,debug:r.debug??false},this.logger=createLogger("SDK.Processor",{enabled:this.config.debug,level:"debug"});}setServerActionHandler(e){this.serverActionHandler=e;}async execute(e){if(this.isExecuting)throw new Error("Already executing commands");this.isExecuting=true,this.shouldAbort=false;let t=[],n=null;try{for(let r=0;r<e.length;r++){if(this.shouldAbort){this.log("Execution aborted");break}let o=e[r],s=["click","type","select","scroll"].includes(o.type),a=n&&["navigate","wait_for_route"].includes(n);s&&a&&(this.log("Auto-waiting for DOM stability before:",o.type),await this.navController.waitForDOMStable()),this.emit("stateChange",{isExecuting:!0,currentCommand:o,currentIndex:r,totalCommands:e.length,description:this.describeCommand(o)}),this.emit("commandStart",o,r);let c=await this.executeCommand(o);if(t.push(c),this.emit("commandComplete",c),n=o.type,!c.success){this.logger.warn("Command failed, stopping execution",{type:o.type,error:c.error,result:c.result});break}r<e.length-1&&await new Promise(u=>setTimeout(u,this.config.commandDelay));}return this.emit("complete",t),t}catch(r){let o=r instanceof Error?r:new Error(String(r));throw this.logger.error("Execution error",o),this.emit("error",o),o}finally{this.isExecuting=false,this.emit("stateChange",{isExecuting:false,currentCommand:void 0,currentIndex:0,totalCommands:e.length,description:void 0});}}abort(){this.shouldAbort=true;}getIsExecuting(){return this.isExecuting}async executeCommand(e){let t=Date.now();try{switch(e.type){case "navigate":return await this.executeNavigate(e,t);case "wait_for_route":return await this.executeWaitForRoute(e,t);case "wait_for_dom_stable":return await this.executeWaitForDomStable(e,t);case "scan_context":return await this.executeScanContext(e,t);case "click":return await this.executeClick(e,t);case "type":return await this.executeType(e,t);case "select":return await this.executeSelect(e,t);case "scroll":return await this.executeScroll(e,t);case "server_action":return await this.executeServerAction(e,t);case "report_result":return await this.executeReportResult(e,t);default:return this.createResult(e,t,!1,"Unknown command type")}}catch(n){return this.logger.error("Command execution error",{type:e.type,error:String(n)}),this.createResult(e,t,false,String(n))}}async executeNavigate(e,t){return this.log("Navigating to:",e.target),await this.navController.executeNavigation(e.target)?this.createResult(e,t,true):this.createResult(e,t,false,"Navigation failed")}async executeWaitForRoute(e,t){this.log("Waiting for route:",e.target);let n=await this.navController.navigateTo(e.target,e.timeout);return this.createResult(e,t,n,n?void 0:"Route timeout")}async executeWaitForDomStable(e,t){return this.log("Waiting for DOM to stabilize"),await this.navController.waitForDOMStable(),this.createResult(e,t,true)}async executeScanContext(e,t){return this.log("Scanning page context"),this.createResult(e,t,true)}async executeClick(e,t){let n=e.selector,r=this.navController.getCurrentRoute();if(n){if(this.log("Clicking with selector:",n),(await this.executor.click(n)).success)return this.createResult(e,t,true);this.log("Selector failed, trying text fallback:",e.text||n);}if(e.text){let s=this.registry.findActionByLabel(r,e.text,e.context);if(s&&s.selector!==n&&(this.log("Found action by label, clicking:",s.selector),(await this.executor.click(s.selector)).success))return this.createResult(e,t,true)}if(e.text){let s=e.text.toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,""),a=`[data-chatbot-action*="${CSS.escape(s)}"]`;if(this.log("Trying data-chatbot-action selector:",a),(await this.executor.click(a)).success)return this.createResult(e,t,true)}if(e.text){let s=`[aria-label="${CSS.escape(e.text)}"]`;if(this.log("Trying aria-label selector:",s),(await this.executor.click(s)).success)return this.createResult(e,t,true)}if(e.text){let s=e.text.toLowerCase().trim(),a=document.querySelectorAll('button, a, [role="button"], [data-chatbot-action]');for(let c of a){let u=c.textContent?.toLowerCase().trim()||"",h=c.getAttribute("aria-label")?.toLowerCase().trim()||"",E=c.getAttribute("data-chatbot-action")?.toLowerCase().replace(/-/g," ")||"";if(u===s||h===s||u.includes(s)||E===s||E.includes(s.replace(/\s+/g,"-"))){let S="";if(c.id?S=`#${CSS.escape(c.id)}`:c.getAttribute("data-chatbot-action")?S=`[data-chatbot-action="${CSS.escape(c.getAttribute("data-chatbot-action")??"")}"]`:c.getAttribute("aria-label")&&(S=`[aria-label="${CSS.escape(c.getAttribute("aria-label")??"")}"]`),S&&(this.log("Found element by text content, clicking:",S),(await this.executor.click(S)).success))return this.createResult(e,t,true)}}}let o=n?`Element not found or click failed: ${n}`:`No selector found for: ${e.text||"unknown"}`;return this.createResult(e,t,false,o)}async executeType(e,t){let n=e.selector;if(!n&&e.text){let o=this.registry.findActionByLabel(this.navController.getCurrentRoute(),e.text);o&&(n=o.selector);}if(!n)return this.createResult(e,t,false,"No selector provided");this.log("Typing into:",n,"value:",e.value);let r=await this.executor.type(n,e.value,e.clear??true);if(!r.success&&e.text&&r.error?.includes("not found")){let o=this.registry.findActionByLabel(this.navController.getCurrentRoute(),e.text);o&&(r=await this.executor.type(o.selector,e.value,e.clear??true));}return this.createResult(e,t,r.success,r.error)}async executeSelect(e,t){let n=e.selector;if(!n&&e.text){let o=this.registry.findActionByLabel(this.navController.getCurrentRoute(),e.text);o&&(n=o.selector);}if(!n)return this.createResult(e,t,false,"No selector provided");this.log("Selecting:",n,"value:",e.value);let r=await this.executor.select(n,e.value);if(!r.success&&e.text&&r.error?.includes("not found")){let o=this.registry.findActionByLabel(this.navController.getCurrentRoute(),e.text);o&&(r=await this.executor.select(o.selector,e.value));}return this.createResult(e,t,r.success,r.error)}async executeScroll(e,t){let n=e.selector??e.position??{x:0,y:0};this.log("Scrolling to:",n);let r=await this.executor.scroll(n);return this.createResult(e,t,r.success,r.error)}async executeServerAction(e,t){if(!this.serverActionHandler)return this.createResult(e,t,false,"No server action handler set");if(!this.registry.findServerActionById(e.actionId))return this.createResult(e,t,false,`Server action not found: ${e.actionId}`);this.log("Executing server action:",e.actionId);try{let r=await this.serverActionHandler(e.actionId,e.params);return this.createResult(e,t,!0,void 0,r)}catch(r){return this.createResult(e,t,false,String(r))}}async executeReportResult(e,t){return this.log("Report result command executed"),this.createResult(e,t,true)}createResult(e,t,n,r,o){return {command:e,success:n,result:o,error:r,duration:Date.now()-t}}describeCommand(e){switch(e.type){case "click":return e.text?`Click "${e.text}"`:`Click element${e.selector?` (${e.selector})`:""}`;case "type":return e.text?`Type into "${e.text}"`:`Type into element${e.selector?` (${e.selector})`:""}`;case "select":return e.text?`Select "${e.value}" in "${e.text}"`:`Select "${e.value}"${e.selector?` (${e.selector})`:""}`;case "scroll":return e.selector?`Scroll to element (${e.selector})`:e.position?`Scroll to (${e.position.x}, ${e.position.y})`:"Scroll";case "navigate":return `Navigate to "${e.target}"`;case "wait_for_route":return `Wait for route "${e.target}"`;case "wait_for_dom_stable":return "Wait for page to finish loading";case "scan_context":return "Scan page for available actions";case "server_action":return `Execute server action "${e.actionId}"`;case "report_result":return "Report result to server";default:return "Execute action"}}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.listeners.get(e)?.delete(t);}}emit(e,...t){this.listeners.get(e)?.forEach(n=>{try{n(...t);}catch(r){this.logger.error(`Error in ${e} listener`,r);}});}log(...e){this.logger.debug(...e);}};var Oe=class{config;actions=new Map;context=null;logger=createLogger("SDK.ServerAction");constructor(e={}){this.config={defaultTimeout:e.defaultTimeout??3e4,debug:e.debug??false,webhookHeaders:e.webhookHeaders??{},baseUrl:e.baseUrl??""},this.logger=createLogger("SDK.ServerAction",{enabled:this.config.debug,level:"debug"});}setContext(e){this.context=e;}register(e){this.actions.set(e.id,e),this.log(`Registered server action: ${e.id}`);}registerMany(e){for(let t of e)this.register(t);}unregister(e){this.actions.delete(e);}getActions(){return Array.from(this.actions.values())}getAction(e){return this.actions.get(e)}async execute(e,t){let n=this.actions.get(e);if(!n)return {success:false,error:`Server action not found: ${e}`};if(!this.context)return {success:false,error:"No execution context set"};let r=n.parameters.filter(s=>s.required&&!(s.name in t)).map(s=>s.name);if(r.length>0)return {success:false,error:`Missing required parameters: ${r.join(", ")}`};let o={...t};for(let s of n.parameters)!(s.name in o)&&s.defaultValue!==void 0&&(o[s.name]=s.defaultValue);this.log(`Executing server action: ${e}`,o);try{return n.handler?await this.executeHandler(n,o):n.webhookUrl?await this.executeWebhook(n,o):{success:!1,error:"Server action has no handler or webhookUrl"}}catch(s){let a=s instanceof Error?s.message:String(s);return this.log(`Server action error: ${a}`),{success:false,error:a}}}async executeHandler(e,t){if(!e.handler)return {success:false,error:"No handler defined"};let n=e.timeout??this.config.defaultTimeout;return await Promise.race([e.handler(t,this.context),new Promise((o,s)=>setTimeout(()=>s(new Error("Timeout")),n))])}async executeWebhook(e,t){if(!e.webhookUrl)return {success:false,error:"No webhookUrl defined"};let n=e.timeout??this.config.defaultTimeout,r=e.webhookUrl.startsWith("http")?e.webhookUrl:`${this.config.baseUrl}${e.webhookUrl}`,o={"Content-Type":"application/json",...this.config.webhookHeaders};if(e.webhookSecret){let c=await this.generateSignature(JSON.stringify(t),e.webhookSecret);o["X-Signature"]=c;}this.context&&(o["X-Session-Id"]=this.context.sessionId,this.context.authToken&&(o.Authorization=`Bearer ${this.context.authToken}`));let s=new AbortController,a=setTimeout(()=>s.abort(),n);try{let c=await fetch(r,{method:"POST",headers:o,body:JSON.stringify({actionId:e.id,params:t,context:{sessionId:this.context?.sessionId,userId:this.context?.userId,currentRoute:this.context?.currentRoute}}),signal:s.signal});if(clearTimeout(a),!c.ok)return this.logger.warn("Webhook failed",{actionId:e.id,status:c.status}),{success:!1,error:`Webhook failed with status ${c.status}`};let u=await c.json();return this.logger.debug("Webhook success",{actionId:e.id}),{success:!0,data:u}}catch(c){if(clearTimeout(a),c instanceof Error&&c.name==="AbortError")return {success:false,error:"Request timeout"};throw c}}async generateSignature(e,t){if(typeof crypto>"u"||!crypto.subtle)throw new Error("Web Crypto API (crypto.subtle) is unavailable. Webhook HMAC signing requires a secure context (HTTPS). Either serve the page over HTTPS or remove the webhookSecret.");let n=new TextEncoder,r=await crypto.subtle.importKey("raw",n.encode(t),{name:"HMAC",hash:"SHA-256"},false,["sign"]),o=await crypto.subtle.sign("HMAC",r,n.encode(e));return btoa(String.fromCharCode(...new Uint8Array(o)))}log(...e){this.logger.debug(...e);}};var Ht=z.object({type:z.enum(["click","type","navigate","scroll","select","scan_context","wait_for_dom_stable","wait_for_route","server_action","report_result"]),selector:z.string().max(500).optional(),text:z.string().max(1e3).optional(),value:z.string().max(5e3).optional(),target:z.string().max(1e3).refine(i=>/^\//.test(i)||/^https?:\/\//.test(i),"Only relative paths or http(s) URLs are allowed").optional(),actionId:z.string().max(255).optional(),params:z.record(z.string(),z.unknown()).optional(),context:z.string().max(500).optional()}),Ft=z.object({type:z.literal("command"),batchId:z.string().max(255),commands:z.array(Ht).max(50),message:z.string().max(5e3).optional()}),Ut=z.object({id:z.string(),role:z.enum(["user","assistant","system"]),content:z.string().max(32e3),timestamp:z.number(),status:z.enum(["sending","sent","error"]).optional()}),_e=createLogger("SDK.Storage",{enabled:true,level:"warn"});function zt(i){let e=null;return function(n){typeof window>"u"||(e&&clearTimeout(e),e=setTimeout(()=>{try{let r=n.slice(-100);localStorage.setItem(`${i}-messages`,JSON.stringify(r));}catch(r){_e.warn("Failed to save messages to localStorage",r);try{let o=n.slice(-50);localStorage.setItem(`${i}-messages`,JSON.stringify(o));}catch(o){_e.warn("Failed to save even reduced messages",o);}}},500));}}function qt(i){let e=zt(i);return function(n,r){let o;switch(r.type){case "ADD_MESSAGE":return o={...n,messages:[...n.messages,r.message]},e(o.messages),o;case "UPDATE_MESSAGE":return o={...n,messages:n.messages.map(s=>s.id===r.id?{...s,...r.updates}:s)},e(o.messages),o;case "SET_MESSAGES":return o={...n,messages:r.messages},e(o.messages),o;case "CLEAR_MESSAGES":return o={...n,messages:[]},e([]),o;case "SET_MODE":return {...n,mode:r.mode};case "SET_CONNECTION_STATE":return {...n,connectionState:r.state};case "SET_EXECUTING":return {...n,isExecuting:r.isExecuting};case "SET_EXECUTION_STATE":return {...n,executionState:r.state};case "SET_ERROR":return {...n,error:r.error};case "CLEAR_ERROR":return {...n,error:null};default:return n}}}function Vt(i="chatbot"){let e=[],t="ask";if(typeof window<"u"){try{let r=localStorage.getItem(`${i}-messages`);if(r){let o=JSON.parse(r);Array.isArray(o)?e=o.filter(a=>{let c=Ut.safeParse(a);return c.success||_e.warn("Skipping invalid persisted message",a),c.success}):localStorage.removeItem(`${i}-messages`);}}catch(r){_e.warn("Failed to load messages from localStorage",r);}let n=localStorage.getItem(`${i}-mode`);(n==="ask"||n==="navigate")&&(t=n);}return {messages:e,mode:t,connectionState:"disconnected",isExecuting:false,executionState:null,error:null}}function Kt({apiKey:i,serverUrl:e,navigationAdapter:t,serverActions:n=[],config:r,options:o,routes:s,debug:a$1=false,autoConnect:c=true,children:u}){let h=useMemo(()=>`chatbot-${i.slice(0,8)}`,[i]),E=useMemo(()=>createLogger("SDK",{enabled:a$1,level:"debug"}),[a$1]),S=useMemo(()=>normalizeWidgetConfig(r??void 0),[r]),D=useMemo(()=>{let l={...S};return o?.theme&&(l.theme={...l.theme,...o.theme}),{...l,...o,theme:l.theme}},[S,o]),pe=useMemo(()=>qt(h),[h]),[R,p]=useReducer(pe,h,Vt),me=useRef(R.messages),[J,V]=useState(()=>{if(typeof window<"u"){let l=localStorage.getItem(`${h}-widget-open`);if(l!==null)return l==="true"}return o?.defaultOpen??false}),[te,Pe]=useState(null),$=te??D?.voiceLanguage??void 0,be=useRef(false);useEffect(()=>{if(be.current)return;let l=D.defaultMode;(l==="ask"||l==="navigate")&&(p({type:"SET_MODE",mode:l}),be.current=true);},[D.defaultMode]),useEffect(()=>{typeof window<"u"&&localStorage.setItem(`${h}-widget-open`,String(J));},[J,h]),useEffect(()=>{me.current=R.messages;},[R.messages]),useEffect(()=>{typeof window<"u"&&localStorage.setItem(`${h}-mode`,R.mode);},[R.mode,h]);let A=useRef(null),Q=useRef(null),O=useRef(new Map),G=useRef(null),$e=useRef(null),y=useRef(null),ve=useRef(null),We=useRef(null),F=useRef(null),j=useRef(null),ne=useRef(void 0);useEffect(()=>{ne.current=s;},[s]);let K=useMemo(()=>t??Ze(),[t]);useEffect(()=>{let l=new ce({serverUrl:e,apiKey:i,debug:a$1});return A.current=l,l.on("connected",({sessionId:f})=>{_("Connected, session:",f),p({type:"SET_CONNECTION_STATE",state:"connected"});}),l.on("authenticated",({sessionId:f})=>{let m=j.current,v=K.getCurrentPath();m&&m.setContext({sessionId:f,currentRoute:v});}),l.on("disconnected",()=>{p({type:"SET_CONNECTION_STATE",state:"disconnected"});}),l.on("reconnecting",({attempt:f,maxAttempts:m})=>{_(`Reconnecting ${f}/${m}`),p({type:"SET_CONNECTION_STATE",state:"reconnecting"});}),l.on("reconnect_failed",()=>{p({type:"SET_CONNECTION_STATE",state:"failed"}),p({type:"SET_ERROR",error:new Error("Connection failed")});}),l.on("error",({error:f})=>{p({type:"SET_ERROR",error:f});}),l.on("message",f=>{g.current(f);}),c&&(l.connect(),p({type:"SET_CONNECTION_STATE",state:"connecting"})),()=>{l.destroy(),A.current=null;}},[e,i,a$1,c]),useEffect(()=>{let l=new ke({debug:a$1}),f=new Te({debug:a$1}),m=new Me({debug:a$1}),v=new Ie({debug:a$1}),x=new Oe({debug:a$1});y.current=l,$e.current=f,ve.current=m,We.current=v,j.current=x;let H=b=>{G.current=b,A.current?.send({type:"context",context:b});},C=b=>{x.setContext({sessionId:A.current?.getSessionId()??"",currentRoute:b});},U=()=>{let b=Q.current,B=b?b.getCurrentRoute():typeof window<"u"?window.location.pathname:"/",Ve=f.scan();l.registerDiscoveredActions(B,Ve);let He={...m.build(Ve,l.getServerActions(),B),...s?.length?{routes:s}:{}};return C(He.route),H(He),He},L=new le(K,{debug:a$1,onDOMStable:()=>U()});Q.current=L,L.setScanner(async()=>U());let z=new De(v,L,l,{debug:a$1});F.current=z,z.setServerActionHandler(async(b,B)=>x.execute(b,B));let ae=[];a$1&&(ae.push(z.on("commandStart",(b,B)=>{_("Command start:",{index:B,type:b.type,command:b});})),ae.push(z.on("commandComplete",b=>{_("Command complete:",{type:b.command.type,success:b.success,duration:b.duration,error:b.error});})),ae.push(z.on("complete",b=>{_("Command batch complete:",{total:b.length,failed:b.filter(B=>!B.success).length});})),ae.push(z.on("error",b=>{_("Command processor error:",b);}))),n.forEach(b=>{O.current.set(b.id,b),l.registerServerAction(b),x.register(b);}),f.observe(b=>{l.registerDiscoveredActions(L.getCurrentRoute(),b);let B={...m.build(b,l.getServerActions(),L.getCurrentRoute()),...s?.length?{routes:s}:{}};C(B.route),H(B);});let pt=L.onRouteChange(()=>{C(L.getCurrentRoute()),U();});return typeof window<"u"&&(document.readyState==="complete"?(C(L.getCurrentRoute()),U()):window.addEventListener("load",()=>{C(L.getCurrentRoute()),U();},{once:true})),()=>{f.disconnect(),z.abort(),ae.forEach(b=>b()),pt();}},[K,a$1,s]),useEffect(()=>{let l=y.current,f=j.current;!l||!f||n.forEach(m=>{O.current.set(m.id,m),l.registerServerAction(m),f.register(m);});},[n]);let Z=useRef([]),re=useRef(false),oe=useCallback(async()=>{if(!(re.current||Z.current.length===0)){re.current=true;try{for(;Z.current.length>0;){let l=Z.current.shift();await Be(l.commands,l.batchId);}}finally{re.current=false;}}},[]),ie=useCallback((l,f)=>{Z.current.push({commands:l,batchId:f}),oe();},[oe]),Be=useCallback(async(l,f)=>{let m=F.current;if(!m)return;p({type:"SET_EXECUTING",isExecuting:true});let v=[];v.push(m.on("stateChange",x=>{p({type:"SET_EXECUTION_STATE",state:x}),p({type:"SET_EXECUTING",isExecuting:x.isExecuting});})),v.push(m.on("error",x=>{p({type:"SET_ERROR",error:x});}));try{let x=await m.execute(l),H=A.current;x.forEach(C=>{H&&(C.command.type==="server_action"?H.send({type:"action_result",actionId:C.command.actionId,success:C.success,result:C.result,error:C.error,commandId:f}):H.send({type:"action_result",actionId:C.command.type,success:C.success,error:C.error,commandId:f}));});}catch(x){let H=x instanceof Error?x:new Error(String(x));p({type:"SET_ERROR",error:H});let C=A.current,U=H.message||"Execution failed";l.forEach(L=>{if(!C)return;let z=L.type==="server_action"?L.actionId:L.type;C.send({type:"action_result",actionId:z,success:false,error:U,commandId:f});});}finally{v.forEach(x=>x()),p({type:"SET_EXECUTING",isExecuting:false}),p({type:"SET_EXECUTION_STATE",state:null});}},[]),g=useRef(()=>{}),T=useCallback(l=>{switch(_("Server message received:",l.type,l),l.type){case "response":{let f=me.current.find(v=>v.id===l.messageId);l.isFinal===false?f&&f.role==="assistant"?p({type:"UPDATE_MESSAGE",id:f.id,updates:{content:f.content+l.message,timestamp:Date.now(),status:"sending"}}):p({type:"ADD_MESSAGE",message:{id:l.messageId,role:"assistant",content:l.message,timestamp:Date.now(),status:"sending"}}):f&&f.role==="assistant"?p({type:"UPDATE_MESSAGE",id:f.id,updates:{content:l.message,timestamp:Date.now(),status:"sent"}}):p({type:"ADD_MESSAGE",message:{id:l.messageId,role:"assistant",content:l.message,timestamp:Date.now(),status:"sent"}});}break;case "command":{let f=Ft.safeParse(l);if(!f.success){_("Rejected invalid command message from server:",f.error.issues);break}let m=f.data;_("Received commands:",m.commands);let v=m.commands,x=m.batchId;if(m.message&&p({type:"ADD_MESSAGE",message:{id:createMessageId(),role:"assistant",content:m.message,timestamp:Date.now(),commands:v.length>0?v:void 0}}),v.length===0)break;if(!F.current){p({type:"SET_ERROR",error:new Error("Action runner not ready")}),v.forEach(C=>{let U=C.type==="server_action"?C.actionId:C.type;A.current&&A.current.send({type:"action_result",actionId:U,success:false,error:"Action runner not ready",commandId:x});});break}ie(v,x);break}case "typing":break;case "server_action_result":_("Server action result:",l.actionId,l.result);break;case "error":_("Server error:",l.code,l.error,l.details),p({type:"SET_ERROR",error:new Error(l.error)});break;case "request_context":G.current&&A.current&&A.current.send({type:"context",context:G.current});break}},[ie]);useEffect(()=>{g.current=T;},[T]);let W=useCallback(l=>{let f=createMessageId();_("Sending message:",{messageId:f,mode:R.mode,length:l.length,connectionState:R.connectionState,route:G.current?.route??K.getCurrentPath()}),p({type:"ADD_MESSAGE",message:{id:f,role:"user",content:l,timestamp:Date.now(),status:"sending"}});let m=G.current??{route:K.getCurrentPath(),title:typeof document<"u"?document.title:"",actions:[],serverActions:Array.from(O.current.values()),content:{headings:[],mainContent:"",forms:[]},timestamp:Date.now(),...ne.current?.length?{routes:ne.current}:{}},v=te??D?.voiceLanguage??void 0;A.current?.send({type:"message",content:l,context:m,mode:R.mode,messageId:f,...v!=null?{locale:v}:{}}),p({type:"UPDATE_MESSAGE",id:f,updates:{status:"sent"}});},[R.mode,K,te,D?.voiceLanguage]),ye=useCallback(l=>{Pe(l??null);},[]),xe=useCallback(l=>{p({type:"SET_MODE",mode:l});},[]),Ee=useCallback(async(l,f)=>{let m=j.current;if(!m)throw new Error("Server action bridge not ready");if(!m.getAction(l)){let x=O.current.get(l);x&&m.register(x);}let v=await m.execute(l,f??{});return A.current&&A.current.send({type:"action_result",actionId:l,success:v.success,result:v.data,error:v.error}),v},[]),Se=useCallback(l=>{O.current.set(l.id,l),y.current?.registerServerAction(l),j.current?.register(l),E.debug("Registered server action:",l.id);},[E]),we=useCallback(()=>{p({type:"CLEAR_MESSAGES"});},[]),se=useCallback(()=>{p({type:"CLEAR_ERROR"});},[]),Ce=useCallback(()=>{F.current?.abort();},[]),Re=useCallback(()=>{p({type:"SET_CONNECTION_STATE",state:"connecting"}),A.current?.connect();},[]),Ae=useCallback(()=>{A.current?.disconnect(),p({type:"SET_CONNECTION_STATE",state:"disconnected"});},[]);function _(...l){E.debug(...l);}let ee=useMemo(()=>({widgetConfig:D,messages:R.messages,mode:R.mode,connectionState:R.connectionState,isExecuting:R.isExecuting,executionState:R.executionState,error:R.error,isWidgetOpen:J,setWidgetOpen:V,voiceLanguage:$,setVoiceLanguage:ye,sendMessage:W,setMode:xe,executeAction:Ee,registerServerAction:Se,clearMessages:we,clearError:se,stopExecution:Ce,connect:Re,disconnect:Ae,isConnected:R.connectionState==="connected"}),[D,R,J,$,ye,W,xe,Ee,Se,we,se,Ce,Re,Ae]);return jsx(a.Provider,{value:ee,children:u})}var dt=`
|
|
1
|
+
import {a,c,d,e,f}from'./chunk-FTD7P2DD.js';import qe,{useMemo,useReducer,useRef,useState,useEffect,useCallback}from'react';import {z}from'zod';import {createLogger,normalizeWidgetConfig,createMessageId}from'@navsi.ai/shared';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var mt=z.object({type:z.string().min(1).max(50)}).passthrough(),bt=z.object({type:z.literal("auth_success"),sessionId:z.string().max(255),accessToken:z.string().max(4096),refreshToken:z.string().max(4096),expiresAt:z.number(),reconnectToken:z.string().max(255).optional()}).passthrough(),vt=z.object({type:z.literal("token_refreshed"),accessToken:z.string().max(4096),refreshToken:z.string().max(4096),expiresAt:z.number()}).passthrough(),Fe=class{queue=[];maxSize;constructor(e=100){this.maxSize=e;}enqueue(e){this.queue.length>=this.maxSize&&this.queue.shift(),this.queue.push(e);}dequeueAll(){let e=[...this.queue];return this.queue=[],e}get length(){return this.queue.length}clear(){this.queue=[];}},ce=class i{ws=null;config;state="disconnected";logger=createLogger("SDK.WebSocket");reconnectAttempts=0;reconnectTimeout=null;heartbeatInterval=null;lastPongTime=0;messageQueue=new Fe;sessionId=null;refreshToken=null;tokenExpiresAt=0;tokenRefreshTimeout=null;listeners=new Map;constructor(e){this.config={serverUrl:e.serverUrl,apiKey:e.apiKey,autoReconnect:e.autoReconnect??true,maxReconnectAttempts:e.maxReconnectAttempts??10,reconnectDelay:e.reconnectDelay??1e3,heartbeatInterval:e.heartbeatInterval??3e4,debug:e.debug??false},this.logger=createLogger("SDK.WebSocket",{enabled:this.config.debug,level:"debug"});}connect(){if(this.state==="connecting"||this.state==="connected"){this.log("Already connected or connecting");return}this.setState("connecting"),this.createWebSocket();}disconnect(){this.closeSocket(),this.setState("disconnected"),this.log("Disconnected");}destroy(){this.cleanup(),this.setState("disconnected"),this.log("Destroyed");}send(e){this.state==="connected"&&this.ws?.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify(e)),this.log("Sent message:",e.type,Qe(e))):(this.messageQueue.enqueue(e),this.log("Queued message (offline):",e.type,Qe(e)));}getState(){return this.state}getSessionId(){return this.sessionId}isConnected(){return this.state==="connected"}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.listeners.get(e)?.delete(t);}}emit(e,t){this.listeners.get(e)?.forEach(n=>{try{n(t);}catch(r){this.logger.error(`Error in ${e} listener`,r);}});}createWebSocket(){try{let e=new URL(this.config.serverUrl);this.sessionId&&e.searchParams.set("sessionId",this.sessionId);let t=e.toString();this.ws=new WebSocket(t),this.ws.onopen=this.handleOpen.bind(this),this.ws.onmessage=this.handleMessage.bind(this),this.ws.onclose=this.handleClose.bind(this),this.ws.onerror=this.handleError.bind(this);}catch(e){this.logger.error("Failed to create WebSocket",e),this.handleConnectionFailure();}}handleOpen(){this.log("WebSocket connected, sending auth message..."),this.ws?.send(JSON.stringify({type:"auth",apiKey:this.config.apiKey,sessionId:this.sessionId}));}handleMessage(e){try{let t=JSON.parse(e.data),n=mt.safeParse(t);if(!n.success){this.logger.warn("Invalid server message shape",n.error.issues);return}let r=t;switch(this.log("Received message:",r.type),r.type){case "connected":this.handleConnected();break;case "auth_success":{let o=bt.safeParse(r);if(!o.success){this.logger.warn("Invalid auth_success message",o.error.issues);return}this.handleAuthSuccess(o.data);break}case "auth_error":this.handleAuthError(r);break;case "pong":this.handlePong(r);break;case "token_refreshed":{let o=vt.safeParse(r);if(!o.success){this.logger.warn("Invalid token_refreshed message",o.error.issues);return}this.handleTokenRefreshed(o.data);break}default:this.emit("message",r);}}catch(t){this.logger.warn("Failed to parse message",t);}}static NON_RETRIABLE_CLOSE_CODES=new Set([1008,4001,4003,4004,4010]);handleClose(e){this.log("WebSocket closed:",e.code,e.reason),this.stopHeartbeat(),this.state!=="disconnected"&&(this.emit("disconnected",{reason:e.reason,code:e.code}),this.config.autoReconnect&&!i.NON_RETRIABLE_CLOSE_CODES.has(e.code)?this.scheduleReconnect():this.setState("disconnected"));}handleError(e){this.logger.error("WebSocket error",e),this.emit("error",{error:new Error("WebSocket error")});}handleConnected(){this.log("Server connection acknowledged");}handleAuthSuccess(e){this.sessionId=e.sessionId,this.refreshToken=e.refreshToken,this.tokenExpiresAt=e.expiresAt,this.reconnectAttempts=0,this.setState("connected"),this.startHeartbeat(),this.scheduleTokenRefresh(),this.flushMessageQueue(),this.emit("authenticated",{sessionId:e.sessionId,expiresAt:e.expiresAt}),this.emit("connected",{sessionId:e.sessionId}),this.log("Authenticated successfully, session:",e.sessionId);}handleAuthError(e){this.logger.warn("Authentication failed",e.error),this.emit("error",{error:new Error(e.error),code:e.code}),this.disconnect();}scheduleTokenRefresh(){this.tokenRefreshTimeout&&clearTimeout(this.tokenRefreshTimeout);let e=Math.max(0,this.tokenExpiresAt-Date.now()-300*1e3);this.tokenRefreshTimeout=setTimeout(()=>{this.refreshAccessToken();},e),this.log("Token refresh scheduled in",Math.round(e/1e3),"seconds");}refreshAccessToken(){!this.refreshToken||this.state!=="connected"||(this.log("Refreshing token..."),this.ws?.send(JSON.stringify({type:"token_refresh",refreshToken:this.refreshToken})));}handleTokenRefreshed(e){this.refreshToken=e.refreshToken,this.tokenExpiresAt=e.expiresAt,this.scheduleTokenRefresh(),this.emit("token_refreshed",{expiresAt:e.expiresAt}),this.log("Token refreshed successfully");}startHeartbeat(){this.stopHeartbeat(),this.lastPongTime=Date.now(),this.heartbeatInterval=setInterval(()=>{if(this.state==="connected"){if(Date.now()-this.lastPongTime>this.config.heartbeatInterval*2){this.logger.warn("Heartbeat timeout, reconnecting..."),this.ws?.close();return}this.ws?.send(JSON.stringify({type:"ping",timestamp:Date.now()})),this.log("Sent ping");}},this.config.heartbeatInterval);}stopHeartbeat(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null);}handlePong(e){this.lastPongTime=Date.now();let t=Date.now()-e.timestamp;this.log("Received pong, latency:",t,"ms");}scheduleReconnect(){if(this.reconnectAttempts>=this.config.maxReconnectAttempts){this.handleConnectionFailure();return}this.setState("reconnecting"),this.reconnectAttempts++;let e=Math.min(this.config.reconnectDelay*Math.pow(2,this.reconnectAttempts-1),3e4);this.log(`Reconnecting in ${e}ms (attempt ${this.reconnectAttempts}/${this.config.maxReconnectAttempts})`),this.emit("reconnecting",{attempt:this.reconnectAttempts,maxAttempts:this.config.maxReconnectAttempts}),this.reconnectTimeout=setTimeout(()=>{this.createWebSocket();},e);}handleConnectionFailure(){this.setState("failed"),this.emit("reconnect_failed",{reason:"Max reconnection attempts reached"}),this.logger.error("Connection failed - max reconnection attempts reached");}flushMessageQueue(){let e=this.messageQueue.dequeueAll();e.length>0&&(this.log(`Flushing ${e.length} queued messages`),e.forEach(t=>this.send(t)));}setState(e){this.state!==e&&(this.log("State:",this.state,"->",e),this.state=e);}closeSocket(){if(this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null),this.tokenRefreshTimeout&&(clearTimeout(this.tokenRefreshTimeout),this.tokenRefreshTimeout=null),this.stopHeartbeat(),this.ws){let e=this.ws;if(e.onopen=null,e.onmessage=null,e.onclose=null,e.onerror=null,this.ws=null,e.readyState===WebSocket.CONNECTING||e.readyState===WebSocket.OPEN)try{e.close(1e3,"Client disconnect");}catch{}}}cleanup(){this.closeSocket(),this.listeners.clear();}log(...e){this.logger.debug(...e);}};function Qe(i){switch(i.type){case "message":return {messageId:i.messageId,mode:i.mode,length:i.content.length,route:i.context?.route};case "context":return {route:i.context?.route,actions:i.context?.actions?.length??0,headings:i.context?.content?.headings?.length??0};case "action_result":return {actionId:i.actionId,success:i.success,commandId:i.commandId};case "server_action_request":return {actionId:i.actionId,requestId:i.requestId};case "auth":return {hasSessionId:!!i.sessionId};case "token_refresh":return {};case "ping":return {timestamp:i.timestamp};default:return {}}}function en(i){return new ce(i)}function Ze(i="/"){let e=i,t=new Set;return {navigate(n){e=n,t.forEach(r=>r(n));},getCurrentPath(){return e},onRouteChange(n){return t.add(n),()=>t.delete(n)},async waitForRoute(n,r=1e4){return new Promise(o=>{if(e===n){o(true);return}let s=this.onRouteChange(a=>{a===n&&(s(),o(true));});setTimeout(()=>{s(),o(e===n);},r);})}}}var le=class{adapter;config;scanCallback=null;logger=createLogger("SDK.Navigation");constructor(e,t={}){this.adapter=e,this.config={domStabilityDelay:t.domStabilityDelay??300,domStabilityTimeout:t.domStabilityTimeout??5e3,debug:t.debug??false,onDOMStable:t.onDOMStable},this.logger=createLogger("SDK.Navigation",{enabled:this.config.debug,level:"debug"});}setScanner(e){this.scanCallback=e;}getCurrentRoute(){return this.adapter.getCurrentPath()}async navigateTo(e,t){if(this.adapter.getCurrentPath()===e)return this.log("Already on route:",e),true;this.log("Navigating to:",e),this.adapter.navigate(e);let r=await this.adapter.waitForRoute(e,t);return r||this.log("Navigation timeout for route:",e),r}async executeNavigation(e){if(!await this.navigateTo(e))return this.log("Navigation failed to:",e),null;if(await this.waitForDOMStable(),this.scanCallback){let n=await this.scanCallback();return this.log("Rescanned context on route:",e),n}return null}async waitForDOMStable(){this.logger.debug("Waiting for DOM stability",{delayMs:this.config.domStabilityDelay,timeoutMs:this.config.domStabilityTimeout});let e=()=>{this.config.onDOMStable?.();};return new Promise(t=>{let n=false,r=()=>{n||(n=true,e(),t());};if(typeof document>"u"||typeof MutationObserver>"u"){r();return}let o,s,a=Date.now(),c=()=>{u.disconnect(),clearTimeout(o),clearTimeout(s);},u=new MutationObserver(()=>{if(clearTimeout(o),Date.now()-a>=this.config.domStabilityTimeout){c(),this.log("DOM stability timeout reached"),r();return}o=setTimeout(()=>{c(),this.log("DOM is stable"),r();},this.config.domStabilityDelay);});u.observe(document.body,{childList:true,subtree:true,attributes:false}),o=setTimeout(()=>{c(),this.log("DOM is stable (no initial mutations)"),r();},this.config.domStabilityDelay),s=setTimeout(()=>{c(),this.log("DOM stability max timeout reached"),r();},this.config.domStabilityTimeout);})}onRouteChange(e){return this.adapter.onRouteChange(e)}log(...e){this.logger.debug(...e);}};function on(i,e){return new le(i,e)}var yt=["button:not([disabled])","a[href]:not([disabled])",'input:not([type="hidden"]):not([disabled])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[contenteditable="plaintext-only"]','[role="textbox"]','[role="searchbox"]','[role="combobox"]','[role="checkbox"]','[role="switch"]','[role="radio"]','[role="button"]:not([disabled])','[role="link"]','[role="menuitem"]','[role="tab"]',"[onclick]","[data-chatbot-action]"],xt=["[data-chatbot-ignore]",'[aria-hidden="true"]',"[hidden]",".chatbot-widget",".navsi-chatbot-container",'[type="password"]','[autocomplete*="cc-"]'];function Et(i){let e=i.getAttribute("data-chatbot-action");if(e)return `[data-chatbot-action="${e}"]`;if(i.id)return `#${CSS.escape(i.id)}`;let t=i.getAttribute("data-testid");if(t)return `[data-testid="${CSS.escape(t)}"]`;let n=i.getAttribute("aria-label");if(n){let o=`[aria-label="${CSS.escape(n)}"]`;if(document.querySelectorAll(o).length===1)return o}let r=i.getAttribute?.("name");if(r&&/^(input|select|textarea|button)$/i.test(i.tagName)){let o=`${i.tagName.toLowerCase()}[name="${CSS.escape(r)}"]`;if(document.querySelectorAll(o).length===1)return o}if(i.className&&typeof i.className=="string"){let o=i.className.split(/\s+/).filter(Boolean).slice(0,3);if(o.length>0){let s=`${i.tagName.toLowerCase()}.${o.map(c=>CSS.escape(c)).join(".")}`;if(document.querySelectorAll(s).length===1)return s}}return St(i)}function St(i){let e=[],t=i;for(;t&&t!==document.body;){let n=t.tagName.toLowerCase();if(t.id){n=`#${CSS.escape(t.id)}`,e.unshift(n);break}let r=t.parentElement;if(r){let o=t.tagName,s=r.children,a=[];for(let c=0;c<s.length;c++)s[c].tagName===o&&a.push(s[c]);if(a.length>1){let c=a.indexOf(t)+1;n+=`:nth-of-type(${c})`;}}e.unshift(n),t=r;}return e.join(" > ")}function wt(i){let e=window.getComputedStyle(i);if(e.display==="none"||e.visibility==="hidden"||e.opacity==="0")return false;let t=i.getBoundingClientRect();return !(t.width===0&&t.height===0||i.closest('[aria-hidden="true"]'))}function Ct(i){for(let e of xt)if(i.matches(e)||i.closest(e))return true;return false}function Rt(i){let e=i.tagName.toLowerCase(),t=i.getAttribute("role")?.toLowerCase();if(e==="input"){let n=i.type;return n==="checkbox"||n==="radio"?"click":"type"}return e==="textarea"?"type":e==="select"?"select":t==="textbox"||t==="searchbox"?"type":"click"}function At(i){let e=i.getAttribute("data-chatbot-action");if(e)return e.replace(/-/g," ");let t=i.getAttribute("aria-label");if(t)return t;let n=i.getAttribute("aria-labelledby");if(n){let c=n.split(/\s+/).map(u=>document.getElementById(u)?.textContent?.trim()).filter(Boolean).join(" ");if(c)return c}let r=i.getAttribute("title");if(r)return r;let o=i.textContent?.trim();if(o&&o.length<50)return o;let s=i.getAttribute("placeholder");if(s)return s;let a=i.getAttribute("name");if(a)return a.replace(/[-_]/g," ");if(i.id){let c=document.querySelector(`label[for="${i.id}"]`);if(c?.textContent)return c.textContent.trim()}return i.tagName.toLowerCase()}var Tt=["tr",'[role="row"]',"article",'[role="listitem"]',"section",'[role="group"]',"main",'[role="region"]'],nt=120;function kt(i){let e=i,t=0,n=8;for(;e&&e!==document.body&&t<n;){for(let r of Tt)try{if(e.matches(r)){let o=e.textContent?.trim().replace(/\s+/g," ");if(o&&o.length>0)return o.length>nt?o.slice(0,nt)+"\u2026":o;break}}catch{}e=e.parentElement,t++;}}function Mt(i){let e=i.parentElement,t=0,n=5;for(;e&&t<n;){let r=e.querySelector("h1, h2, h3, h4, h5, h6");if(r?.textContent)return r.textContent.trim();let o=e.previousElementSibling;for(;o;){if(/^H[1-6]$/.test(o.tagName))return o.textContent?.trim();o=o.previousElementSibling;}e=e.parentElement,t++;}}var Te=class{config;mutationObserver=null;scanTimeout=null;onChangeCallback=null;logger=createLogger("SDK.Scanner");constructor(e={}){this.config={root:e.root??(typeof document<"u"?document.body:null),debug:e.debug??false,maxActions:e.maxActions??100,debounceMs:e.debounceMs??300},this.logger=createLogger("SDK.Scanner",{enabled:this.config.debug,level:"debug"});}scan(){if(typeof document>"u")return [];let e=this.config.root??document.body,t=[],n=typeof window<"u"?window.location.pathname:"/",r=yt.join(", "),o=this.collectInteractiveElements(e,r);this.log(`Found ${o.length} potential interactive elements`);for(let s of o){if(t.length>=this.config.maxActions)break;if(Ct(s)||!wt(s))continue;let a=this.createElement(s,n);a&&t.push(a);}return this.log(`Discovered ${t.length} actions`),t}createElement(e,t){try{let n=Et(e),r=At(e),o=Rt(e),s=Mt(e),u={id:`action_${btoa(unescape(encodeURIComponent(n))).replace(/[^a-zA-Z0-9]/g,"").slice(0,16)}`,type:o,selector:n,label:r,route:t,isAutoDiscovered:!0,priority:e.hasAttribute("data-chatbot-action")?10:1},h=kt(e);return (s||h)&&(u.metadata={...s?{context:s}:{},...h?{containerText:h}:{}}),u}catch(n){return this.log("Error creating action:",n),null}}collectInteractiveElements(e,t){let n=new Set,r=[e];for(;r.length>0;){let o=r.shift();if(!o)break;let a=(o).querySelectorAll(t);for(let h of a)n.add(h);let u=(o).querySelectorAll("*");for(let h of u){let E=h.shadowRoot;E&&r.push(E);}}return Array.from(n)}observe(e){typeof MutationObserver>"u"||(this.disconnect(),this.onChangeCallback=e,this.mutationObserver=new MutationObserver(()=>{this.debouncedScan();}),this.mutationObserver.observe(this.config.root??document.body,{childList:true,subtree:true,attributes:true,attributeFilter:["disabled","hidden","aria-hidden"]}));}disconnect(){this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.scanTimeout&&(clearTimeout(this.scanTimeout),this.scanTimeout=null);}debouncedScan(){this.scanTimeout&&clearTimeout(this.scanTimeout),this.scanTimeout=setTimeout(()=>{let e=this.scan();this.onChangeCallback?.(e);},this.config.debounceMs);}log(...e){this.logger.debug(...e);}};var ke=class{actionsByRoute=new Map;serverActions=new Map;manualActions=new Map;debug;logger=createLogger("SDK.Registry");constructor(e={}){this.debug=e.debug??false,this.logger=createLogger("SDK.Registry",{enabled:this.debug,level:"debug"});}registerDiscoveredActions(e,t){this.actionsByRoute.has(e)||this.actionsByRoute.set(e,new Map);let n=this.actionsByRoute.get(e);for(let[r,o]of n)o.isAutoDiscovered&&n.delete(r);for(let r of t){let o=this.manualActions.get(r.id);o?n.set(r.id,{...r,...o}):n.set(r.id,r);}this.log(`Registered ${t.length} discovered actions for route: ${e}`);}registerManualAction(e){this.manualActions.set(e.id,e);let t=this.actionsByRoute.get(e.route);if(t?.has(e.id)){let n=t.get(e.id);t.set(e.id,{...n,...e,isAutoDiscovered:false});}this.log(`Registered manual action: ${e.id}`);}getActionsForRoute(e){let t=this.actionsByRoute.get(e);return t?Array.from(t.values()).sort((n,r)=>(r.priority??0)-(n.priority??0)):[]}findActionById(e){for(let t of this.actionsByRoute.values()){let n=t.get(e);if(n)return n}return null}findActionBySelector(e,t){let n=this.actionsByRoute.get(e);if(!n)return null;for(let r of n.values())if(r.selector===t)return r;return null}findActionByLabel(e,t,n){let r=this.actionsByRoute.get(e);if(!r)return null;let o=t.toLowerCase().trim(),s=n?.toLowerCase().trim(),a=c=>{if(!s)return true;let u=c.metadata?.containerText?.toLowerCase(),h=c.metadata?.context?.toLowerCase();return (u?.includes(s)??false)||(h?.includes(s)??false)};if(s){for(let c of r.values())if(c.label.toLowerCase()===o&&a(c))return c;for(let c of r.values())if(c.label.toLowerCase().includes(o)&&a(c))return c}for(let c of r.values())if(c.label.toLowerCase()===o)return c;for(let c of r.values())if(c.label.toLowerCase().includes(o))return c;return null}clearRoute(e){this.actionsByRoute.delete(e);}clearAll(){this.actionsByRoute.clear();}registerServerAction(e){this.serverActions.set(e.id,e),this.log(`Registered server action: ${e.id}`);}getServerActions(){return Array.from(this.serverActions.values())}findServerActionById(e){return this.serverActions.get(e)??null}findServerActionByName(e){let t=e.toLowerCase().trim();for(let n of this.serverActions.values())if(n.name.toLowerCase()===t)return n;for(let n of this.serverActions.values())if(n.name.toLowerCase().includes(t))return n;return null}removeServerAction(e){this.serverActions.delete(e);}getStats(){let e=0;for(let t of this.actionsByRoute.values())e+=t.size;return {routes:this.actionsByRoute.size,actions:e,serverActions:this.serverActions.size}}log(...e){this.logger.debug(...e);}};function Nt(i){return i.replace(/\s+/g," ").trim()}function It(){if(typeof document>"u")return [];let i=["chatbot","ai assistant","ask mode","navigate mode","navsi","intelligent agent"],e=[],t=document.querySelectorAll("h1, h2, h3, h4, h5, h6");for(let n of t){if(n.closest(".chatbot-widget")||n.closest(".navsi-chatbot-container"))continue;let r=n.textContent?.trim();if(r&&r.length<200){let o=r.toLowerCase();i.some(a=>o.includes(a))||e.push(r);}}return e.slice(0,20)}function Dt(i){if(typeof document>"u")return "";let e=document.querySelector("main")??document.querySelector('[role="main"]')??document.querySelector("article")??document.querySelector(".content")??document.body,t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,{acceptNode:o=>{let s=o.parentElement;if(!s)return NodeFilter.FILTER_REJECT;let a=s.tagName.toLowerCase();return ["script","style","noscript"].includes(a)||s.closest(".chatbot-widget")||s.closest(".navsi-chatbot-container")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),n="",r;for(;(r=t.nextNode())&&n.length<i;){let o=r.textContent?.trim();o&&o.length>0&&(n+=o+" ");}return Nt(n).slice(0,i)}function Ot(){if(typeof document>"u")return [];let i=[],e=document.querySelectorAll("form");for(let t of e){if(t.closest(".chatbot-widget")||t.closest(".navsi-chatbot-container"))continue;let n=[],r=t.querySelectorAll("input, select, textarea");for(let o of r){let s=o;if(s.type==="hidden")continue;let a;s.id&&(a=document.querySelector(`label[for="${s.id}"]`)?.textContent?.trim()),!a&&s.getAttribute("aria-label")&&(a=s.getAttribute("aria-label")??void 0),n.push({name:s.name||s.id||"",type:s.type||s.tagName.toLowerCase(),label:a,placeholder:"placeholder"in s?s.placeholder:void 0,required:s.required});}n.length>0&&i.push({id:t.id||`form_${i.length}`,name:t.name||void 0,action:t.action?(()=>{try{return new URL(t.action).pathname}catch{return}})():void 0,method:t.method||void 0,fields:n});}return i.slice(0,10)}function _t(){return typeof document>"u"?void 0:document.querySelector('meta[name="description"]')?.getAttribute("content")??void 0}var Me=class{config;logger=createLogger("SDK.Context");constructor(e={}){this.config={maxContentLength:e.maxContentLength??2e3,maxActions:e.maxActions??50,debug:e.debug??false},this.logger=createLogger("SDK.Context",{enabled:this.config.debug,level:"debug"});}build(e,t,n){let r=n??(typeof window<"u"?window.location.pathname:"/"),o=typeof document<"u"?document.title:"",s={headings:It(),mainContent:Dt(this.config.maxContentLength),forms:Ot(),metaDescription:_t()},a=e.slice(0,this.config.maxActions),c={route:r,title:o,actions:a,serverActions:t,content:s,timestamp:Date.now()};return this.log("Built page context:",{route:c.route,title:c.title,actions:c.actions.length,serverActions:c.serverActions.length,headings:c.content.headings.length,forms:c.content.forms.length}),c}buildMinimal(e,t,n){return {route:n??(typeof window<"u"?window.location.pathname:"/"),title:typeof document<"u"?document.title:"",actions:e.slice(0,this.config.maxActions),serverActions:t,content:{headings:[],mainContent:"",forms:[]},timestamp:Date.now()}}log(...e){this.logger.debug(...e);}};function ge(i,e){let t=e?.preferVisible??false,n=[document],r=null;for(;n.length>0;){let o=n.shift(),s=o.querySelector(i);if(s){if(!t||X(s))return s;r||(r=s);}let a=o instanceof Document?o.body??o.documentElement:o;if(!a)continue;let c=a.querySelectorAll("*");for(let u of c){let h=u.shadowRoot;h&&n.push(h);}}return t?r:null}async function ue(i,e,t=true){let r=o=>o?!t||X(o):false;return new Promise(o=>{let s=ge(i,{preferVisible:t});if(r(s)){o(s);return}let a=false,c=null,u=null,h=()=>{a=true,c&&clearInterval(c),u&&clearTimeout(u),E.disconnect();},E=new MutationObserver(()=>{if(a)return;let S=ge(i,{preferVisible:t});r(S)&&(h(),o(S));});E.observe(document.body,{childList:true,subtree:true}),c=setInterval(()=>{if(a)return;let S=ge(i,{preferVisible:t});r(S)&&(h(),o(S));},100),u=setTimeout(()=>{if(a)return;h();let S=ge(i,{preferVisible:t});o(r(S)?S:null);},e);})}function X(i){let e=window.getComputedStyle(i);if(e.display==="none"||e.visibility==="hidden"||e.opacity==="0")return false;let t=i.getBoundingClientRect();if(t.width===0&&t.height===0)return false;let n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,o=t.right>0&&t.left<n,s=t.bottom>0&&t.top<r;return o&&s}function Lt(i){let e=i.getBoundingClientRect();return {x:e.left+e.width/2,y:e.top+e.height/2}}function Ue(i,e){let t=i instanceof HTMLInputElement?HTMLInputElement.prototype:HTMLTextAreaElement.prototype,n=Object.getOwnPropertyDescriptor(t,"value")?.set;n?n.call(i,e):i.value=e;}function Ne(i){i.scrollIntoView({behavior:"smooth",block:"center",inline:"center"});}function de(i,e=500){let t=i,n=t.style.outline,r=t.style.transition;t.style.transition="outline 0.2s ease",t.style.outline="3px solid #6366f1",setTimeout(()=>{t.style.outline=n,t.style.transition=r;},e);}async function Pt(i,e,t){i.focus(),Ue(i,""),i.dispatchEvent(new Event("input",{bubbles:true}));for(let n of e){try{typeof InputEvent<"u"&&i.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,data:n,inputType:"insertText"}));}catch{}let r=(i.value??"")+n;Ue(i,r),i.dispatchEvent(new Event("input",{bubbles:true})),i.dispatchEvent(new KeyboardEvent("keydown",{key:n,bubbles:true})),i.dispatchEvent(new KeyboardEvent("keypress",{key:n,bubbles:true})),i.dispatchEvent(new KeyboardEvent("keyup",{key:n,bubbles:true})),t>0&&await new Promise(o=>setTimeout(o,t));}i.dispatchEvent(new Event("change",{bubbles:true}));}async function $t(i,e,t){i.focus(),i.textContent="",i.dispatchEvent(new Event("input",{bubbles:true}));for(let n of e){try{typeof InputEvent<"u"&&i.dispatchEvent(new InputEvent("beforeinput",{bubbles:!0,cancelable:!0,data:n,inputType:"insertText"}));}catch{}i.textContent=(i.textContent??"")+n,i.dispatchEvent(new Event("input",{bubbles:true})),i.dispatchEvent(new KeyboardEvent("keydown",{key:n,bubbles:true})),i.dispatchEvent(new KeyboardEvent("keypress",{key:n,bubbles:true})),i.dispatchEvent(new KeyboardEvent("keyup",{key:n,bubbles:true})),t>0&&await new Promise(r=>setTimeout(r,t));}i.dispatchEvent(new Event("change",{bubbles:true}));}function P(i){let e=i.getBoundingClientRect(),t=i.tagName.toLowerCase(),n={};if(i instanceof HTMLElement)for(let r of Array.from(i.attributes))(r.name.startsWith("data-")||r.name==="aria-label"||r.name==="name"||r.name==="id")&&(n[r.name]=r.value);return {tagName:t,text:(i.textContent??"").trim().slice(0,80),rect:{x:e.x,y:e.y,width:e.width,height:e.height},attributes:n}}var Ie=class i{config;logger=createLogger("SDK.Executor");constructor(e={}){this.config={elementTimeout:e.elementTimeout??6e3,typeDelay:e.typeDelay??30,scrollIntoView:e.scrollIntoView??true,highlightOnInteract:e.highlightOnInteract??true,debug:e.debug??false},this.logger=createLogger("SDK.Executor",{enabled:this.config.debug,level:"debug"});}static RETRY_DELAY_MS=600;static MAX_RETRIES=2;async click(e){let t=Date.now(),n=async()=>{let o=await ue(e,this.config.elementTimeout,true);if(!o)return this.createResult(e,"click",t,false,"Element not found","ELEMENT_NOT_FOUND");if(this.config.scrollIntoView&&!X(o)&&(Ne(o),await new Promise(h=>setTimeout(h,100))),this.config.highlightOnInteract&&de(o),!X(o))return this.createResult(e,"click",t,false,"Element is not visible","NOT_VISIBLE",P(o));let s=o;if(s.disabled===true||s.getAttribute("aria-disabled")==="true")return this.createResult(e,"click",t,false,"Element is disabled","DISABLED",P(o));s.focus();let{x:c,y:u}=Lt(o);try{typeof PointerEvent<"u"&&(o.dispatchEvent(new PointerEvent("pointerover",{bubbles:!0,cancelable:!0,clientX:c,clientY:u})),o.dispatchEvent(new PointerEvent("pointerenter",{bubbles:!0,cancelable:!0,clientX:c,clientY:u})),o.dispatchEvent(new PointerEvent("pointermove",{bubbles:!0,cancelable:!0,clientX:c,clientY:u})));}catch{}o.dispatchEvent(new MouseEvent("mouseover",{bubbles:true,cancelable:true,clientX:c,clientY:u})),o.dispatchEvent(new MouseEvent("mouseenter",{bubbles:true,cancelable:true,clientX:c,clientY:u})),o.dispatchEvent(new MouseEvent("mousemove",{bubbles:true,cancelable:true,clientX:c,clientY:u}));try{typeof PointerEvent<"u"&&(o.dispatchEvent(new PointerEvent("pointerdown",{bubbles:!0,cancelable:!0,button:0,clientX:c,clientY:u})),o.dispatchEvent(new PointerEvent("pointerup",{bubbles:!0,cancelable:!0,button:0,clientX:c,clientY:u})));}catch{}return o.dispatchEvent(new MouseEvent("mousedown",{bubbles:true,cancelable:true,clientX:c,clientY:u})),o.dispatchEvent(new MouseEvent("mouseup",{bubbles:true,cancelable:true,clientX:c,clientY:u})),o.dispatchEvent(new MouseEvent("click",{bubbles:true,cancelable:true,clientX:c,clientY:u})),s.click(),this.log("Clicked:",e),this.createResult(e,"click",t,true,void 0,void 0,P(o))};return (async()=>{let o=null;for(let s=0;s<=i.MAX_RETRIES;s++){s>0&&(this.log(`Click retry ${s}/${i.MAX_RETRIES} for:`,e),await new Promise(a=>setTimeout(a,i.RETRY_DELAY_MS*s)));try{if(o=await n(),o.success)return o}catch(a){o=this.createResult(e,"click",t,false,String(a),"RUNTIME_ERROR");}}return o})()}async type(e,t,n=true){let r=Date.now(),o=async()=>{let a=await ue(e,this.config.elementTimeout,true);if(!a)return this.createResult(e,"type",r,false,"Element not found","ELEMENT_NOT_FOUND");if(!this.isTypeable(a))return this.createResult(e,"type",r,false,"Element is not typeable","TYPE_MISMATCH",P(a));this.config.scrollIntoView&&!X(a)&&(Ne(a),await new Promise(u=>setTimeout(u,100))),this.config.highlightOnInteract&&de(a);let c=P(a);if(!X(a))return this.createResult(e,"type",r,false,"Element is not visible","NOT_VISIBLE",c);if(a instanceof HTMLInputElement||a instanceof HTMLTextAreaElement){let u=a;if(u.disabled||u.getAttribute("aria-disabled")==="true")return this.createResult(e,"type",r,false,"Element is disabled","DISABLED",c);n?await Pt(u,t,this.config.typeDelay):(u.focus(),Ue(u,(u.value??"")+t),u.dispatchEvent(new Event("input",{bubbles:true})),u.dispatchEvent(new Event("change",{bubbles:true})));}else if(a instanceof HTMLElement&&a.isContentEditable){if(a.getAttribute("aria-disabled")==="true")return this.createResult(e,"type",r,false,"Element is disabled","DISABLED",c);await $t(a,t,this.config.typeDelay);}else return this.createResult(e,"type",r,false,"Element is not a supported type target","TYPE_MISMATCH",c);return this.log("Typed into:",e,"text:",t.slice(0,20)+(t.length>20?"...":"")),this.createResult(e,"type",r,true,void 0,void 0,{...c,textLength:t.length})};return (async()=>{let a=null;for(let c=0;c<=i.MAX_RETRIES;c++){c>0&&(this.log(`Type retry ${c}/${i.MAX_RETRIES} for:`,e),await new Promise(u=>setTimeout(u,i.RETRY_DELAY_MS*c)));try{if(a=await o(),a.success)return a}catch(u){a=this.createResult(e,"type",r,false,String(u),"RUNTIME_ERROR");}}return a})()}async select(e,t){let n=Date.now(),r=async()=>{let s=await ue(e,this.config.elementTimeout,true);if(!s)return this.createResult(e,"select",n,false,"Element not found","ELEMENT_NOT_FOUND");if(s.tagName.toLowerCase()!=="select")return this.createResult(e,"select",n,false,"Element is not a select","TYPE_MISMATCH",P(s));if(this.config.scrollIntoView&&!X(s)&&(Ne(s),await new Promise(E=>setTimeout(E,100))),this.config.highlightOnInteract&&de(s),!X(s))return this.createResult(e,"select",n,false,"Element is not visible","NOT_VISIBLE",P(s));let a=s;if(a.disabled||a.getAttribute("aria-disabled")==="true")return this.createResult(e,"select",n,false,"Element is disabled","DISABLED",P(s));let c=false,u="";for(let E of a.options)if(E.value===t||E.textContent?.toLowerCase().includes(t.toLowerCase())){u=E.value,c=true;break}if(!c)return this.createResult(e,"select",n,false,`Option not found: ${t}`,"OPTION_NOT_FOUND",{...P(s),attemptedValue:t});let h=Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,"value")?.set;return h?h.call(a,u):a.value=u,a.dispatchEvent(new Event("input",{bubbles:true})),a.dispatchEvent(new Event("change",{bubbles:true})),this.log("Selected:",e,"value:",t),this.createResult(e,"select",n,true,void 0,void 0,{...P(s),selectedValue:t})};return (async()=>{let s=null;for(let a=0;a<=i.MAX_RETRIES;a++){a>0&&(this.log(`Select retry ${a}/${i.MAX_RETRIES} for:`,e),await new Promise(c=>setTimeout(c,i.RETRY_DELAY_MS*a)));try{if(s=await r(),s.success)return s}catch(c){s=this.createResult(e,"select",n,false,String(c),"RUNTIME_ERROR");}}return s})()}async scroll(e){let t=Date.now(),n=typeof e=="string"?e:`${e.x},${e.y}`;try{if(typeof e=="string"){let r=await ue(e,this.config.elementTimeout,!1);if(!r)return this.createResult(n,"scroll",t,!1,"Element not found","ELEMENT_NOT_FOUND");this.config.highlightOnInteract&&de(r),Ne(r);}else window.scrollTo({left:e.x,top:e.y,behavior:"smooth"});return this.log("Scrolled to:",e),this.createResult(n,"scroll",t,!0,void 0,void 0,typeof e=="string"?(()=>{let r=ge(e);return r?P(r):{selector:e}})():{position:e})}catch(r){return this.createResult(n,"scroll",t,false,String(r),"RUNTIME_ERROR")}}async submit(e){let t=Date.now();try{let n=await ue(e,this.config.elementTimeout,!0);if(!n)return this.createResult(e,"submit",t,!1,"Element not found","ELEMENT_NOT_FOUND");let r=n.tagName.toLowerCase()==="form"?n:n.closest("form");if(!r){let s=n.querySelector('button[type="submit"], input[type="submit"]');return s?this.click(this.generateSelector(s)):this.createResult(e,"submit",t,!1,"No form found","NO_FORM",P(n))}this.config.highlightOnInteract&&de(r);let o=r.querySelector('button[type="submit"], input[type="submit"]');if(typeof r.requestSubmit=="function")r.requestSubmit(o??void 0);else {let s=new Event("submit",{bubbles:!0,cancelable:!0});r.dispatchEvent(s)&&r.submit();}return this.log("Submitted form:",e),this.createResult(e,"submit",t,!0,void 0,void 0,P(r))}catch(n){return this.createResult(e,"submit",t,false,String(n),"RUNTIME_ERROR")}}isTypeable(e){let t=e.tagName.toLowerCase();if(t==="input"){let n=e.type;return ["text","email","password","search","tel","url","number"].includes(n)}return !!(t==="textarea"||e.hasAttribute("contenteditable"))}generateSelector(e){if(e.id)return `#${e.id}`;let t=e.getAttribute("data-testid");return t?`[data-testid="${t}"]`:e.tagName.toLowerCase()}createResult(e,t,n,r,o,s,a){return r||this.logger.warn("Action failed",{action:t,selector:e,error:o,errorCode:s,metadata:a}),{success:r,selector:e,action:t,duration:Date.now()-n,errorCode:s,error:o,metadata:a}}log(...e){this.logger.debug(...e);}};var De=class{config;executor;navController;registry;logger=createLogger("SDK.Processor");isExecuting=false;shouldAbort=false;listeners=new Map;serverActionHandler=null;constructor(e,t,n,r={}){this.executor=e,this.navController=t,this.registry=n,this.config={commandDelay:r.commandDelay??300,commandTimeout:r.commandTimeout??3e4,debug:r.debug??false},this.logger=createLogger("SDK.Processor",{enabled:this.config.debug,level:"debug"});}setServerActionHandler(e){this.serverActionHandler=e;}async execute(e){if(this.isExecuting)throw new Error("Already executing commands");this.isExecuting=true,this.shouldAbort=false;let t=[],n=null;try{for(let r=0;r<e.length;r++){if(this.shouldAbort){this.log("Execution aborted");break}let o=e[r],s=["click","type","select","scroll"].includes(o.type),a=n&&["navigate","wait_for_route"].includes(n);s&&a&&(this.log("Auto-waiting for DOM stability before:",o.type),await this.navController.waitForDOMStable()),this.emit("stateChange",{isExecuting:!0,currentCommand:o,currentIndex:r,totalCommands:e.length,description:this.describeCommand(o)}),this.emit("commandStart",o,r);let c=await this.executeCommand(o);if(t.push(c),this.emit("commandComplete",c),n=o.type,!c.success){this.logger.warn("Command failed, stopping execution",{type:o.type,error:c.error,result:c.result});break}r<e.length-1&&await new Promise(u=>setTimeout(u,this.config.commandDelay));}return this.emit("complete",t),t}catch(r){let o=r instanceof Error?r:new Error(String(r));throw this.logger.error("Execution error",o),this.emit("error",o),o}finally{this.isExecuting=false,this.emit("stateChange",{isExecuting:false,currentCommand:void 0,currentIndex:0,totalCommands:e.length,description:void 0});}}abort(){this.shouldAbort=true;}getIsExecuting(){return this.isExecuting}async executeCommand(e){let t=Date.now();try{switch(e.type){case "navigate":return await this.executeNavigate(e,t);case "wait_for_route":return await this.executeWaitForRoute(e,t);case "wait_for_dom_stable":return await this.executeWaitForDomStable(e,t);case "scan_context":return await this.executeScanContext(e,t);case "click":return await this.executeClick(e,t);case "type":return await this.executeType(e,t);case "select":return await this.executeSelect(e,t);case "scroll":return await this.executeScroll(e,t);case "server_action":return await this.executeServerAction(e,t);case "report_result":return await this.executeReportResult(e,t);default:return this.createResult(e,t,!1,"Unknown command type")}}catch(n){return this.logger.error("Command execution error",{type:e.type,error:String(n)}),this.createResult(e,t,false,String(n))}}async executeNavigate(e,t){return this.log("Navigating to:",e.target),await this.navController.executeNavigation(e.target)?this.createResult(e,t,true):this.createResult(e,t,false,"Navigation failed")}async executeWaitForRoute(e,t){this.log("Waiting for route:",e.target);let n=await this.navController.navigateTo(e.target,e.timeout);return this.createResult(e,t,n,n?void 0:"Route timeout")}async executeWaitForDomStable(e,t){return this.log("Waiting for DOM to stabilize"),await this.navController.waitForDOMStable(),this.createResult(e,t,true)}async executeScanContext(e,t){return this.log("Scanning page context"),this.createResult(e,t,true)}async executeClick(e,t){let n=e.selector,r=this.navController.getCurrentRoute();if(n){if(this.log("Clicking with selector:",n),(await this.executor.click(n)).success)return this.createResult(e,t,true);this.log("Selector failed, trying text fallback:",e.text||n);}if(e.text){let s=this.registry.findActionByLabel(r,e.text,e.context);if(s&&s.selector!==n&&(this.log("Found action by label, clicking:",s.selector),(await this.executor.click(s.selector)).success))return this.createResult(e,t,true)}if(e.text){let s=e.text.toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,""),a=`[data-chatbot-action*="${CSS.escape(s)}"]`;if(this.log("Trying data-chatbot-action selector:",a),(await this.executor.click(a)).success)return this.createResult(e,t,true)}if(e.text){let s=`[aria-label="${CSS.escape(e.text)}"]`;if(this.log("Trying aria-label selector:",s),(await this.executor.click(s)).success)return this.createResult(e,t,true)}if(e.text){let s=e.text.toLowerCase().trim(),a=document.querySelectorAll('button, a, [role="button"], [data-chatbot-action]');for(let c of a){let u=c.textContent?.toLowerCase().trim()||"",h=c.getAttribute("aria-label")?.toLowerCase().trim()||"",E=c.getAttribute("data-chatbot-action")?.toLowerCase().replace(/-/g," ")||"";if(u===s||h===s||u.includes(s)||E===s||E.includes(s.replace(/\s+/g,"-"))){let S="";if(c.id?S=`#${CSS.escape(c.id)}`:c.getAttribute("data-chatbot-action")?S=`[data-chatbot-action="${CSS.escape(c.getAttribute("data-chatbot-action")??"")}"]`:c.getAttribute("aria-label")&&(S=`[aria-label="${CSS.escape(c.getAttribute("aria-label")??"")}"]`),S&&(this.log("Found element by text content, clicking:",S),(await this.executor.click(S)).success))return this.createResult(e,t,true)}}}let o=n?`Element not found or click failed: ${n}`:`No selector found for: ${e.text||"unknown"}`;return this.createResult(e,t,false,o)}async executeType(e,t){let n=e.selector;if(!n&&e.text){let o=this.registry.findActionByLabel(this.navController.getCurrentRoute(),e.text);o&&(n=o.selector);}if(!n)return this.createResult(e,t,false,"No selector provided");this.log("Typing into:",n,"value:",e.value);let r=await this.executor.type(n,e.value,e.clear??true);if(!r.success&&e.text&&r.error?.includes("not found")){let o=this.registry.findActionByLabel(this.navController.getCurrentRoute(),e.text);o&&(r=await this.executor.type(o.selector,e.value,e.clear??true));}return this.createResult(e,t,r.success,r.error)}async executeSelect(e,t){let n=e.selector;if(!n&&e.text){let o=this.registry.findActionByLabel(this.navController.getCurrentRoute(),e.text);o&&(n=o.selector);}if(!n)return this.createResult(e,t,false,"No selector provided");this.log("Selecting:",n,"value:",e.value);let r=await this.executor.select(n,e.value);if(!r.success&&e.text&&r.error?.includes("not found")){let o=this.registry.findActionByLabel(this.navController.getCurrentRoute(),e.text);o&&(r=await this.executor.select(o.selector,e.value));}return this.createResult(e,t,r.success,r.error)}async executeScroll(e,t){let n=e.selector??e.position??{x:0,y:0};this.log("Scrolling to:",n);let r=await this.executor.scroll(n);return this.createResult(e,t,r.success,r.error)}async executeServerAction(e,t){if(!this.serverActionHandler)return this.createResult(e,t,false,"No server action handler set");if(!this.registry.findServerActionById(e.actionId))return this.createResult(e,t,false,`Server action not found: ${e.actionId}`);this.log("Executing server action:",e.actionId);try{let r=await this.serverActionHandler(e.actionId,e.params);return this.createResult(e,t,!0,void 0,r)}catch(r){return this.createResult(e,t,false,String(r))}}async executeReportResult(e,t){return this.log("Report result command executed"),this.createResult(e,t,true)}createResult(e,t,n,r,o){return {command:e,success:n,result:o,error:r,duration:Date.now()-t}}describeCommand(e){switch(e.type){case "click":return e.text?`Click "${e.text}"`:`Click element${e.selector?` (${e.selector})`:""}`;case "type":return e.text?`Type into "${e.text}"`:`Type into element${e.selector?` (${e.selector})`:""}`;case "select":return e.text?`Select "${e.value}" in "${e.text}"`:`Select "${e.value}"${e.selector?` (${e.selector})`:""}`;case "scroll":return e.selector?`Scroll to element (${e.selector})`:e.position?`Scroll to (${e.position.x}, ${e.position.y})`:"Scroll";case "navigate":return `Navigate to "${e.target}"`;case "wait_for_route":return `Wait for route "${e.target}"`;case "wait_for_dom_stable":return "Wait for page to finish loading";case "scan_context":return "Scan page for available actions";case "server_action":return `Execute server action "${e.actionId}"`;case "report_result":return "Report result to server";default:return "Execute action"}}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.listeners.get(e)?.delete(t);}}emit(e,...t){this.listeners.get(e)?.forEach(n=>{try{n(...t);}catch(r){this.logger.error(`Error in ${e} listener`,r);}});}log(...e){this.logger.debug(...e);}};var Oe=class{config;actions=new Map;context=null;logger=createLogger("SDK.ServerAction");constructor(e={}){this.config={defaultTimeout:e.defaultTimeout??3e4,debug:e.debug??false,webhookHeaders:e.webhookHeaders??{},baseUrl:e.baseUrl??""},this.logger=createLogger("SDK.ServerAction",{enabled:this.config.debug,level:"debug"});}setContext(e){this.context=e;}register(e){this.actions.set(e.id,e),this.log(`Registered server action: ${e.id}`);}registerMany(e){for(let t of e)this.register(t);}unregister(e){this.actions.delete(e);}getActions(){return Array.from(this.actions.values())}getAction(e){return this.actions.get(e)}async execute(e,t){let n=this.actions.get(e);if(!n)return {success:false,error:`Server action not found: ${e}`};if(!this.context)return {success:false,error:"No execution context set"};let r=n.parameters.filter(s=>s.required&&!(s.name in t)).map(s=>s.name);if(r.length>0)return {success:false,error:`Missing required parameters: ${r.join(", ")}`};let o={...t};for(let s of n.parameters)!(s.name in o)&&s.defaultValue!==void 0&&(o[s.name]=s.defaultValue);this.log(`Executing server action: ${e}`,o);try{return n.handler?await this.executeHandler(n,o):n.webhookUrl?await this.executeWebhook(n,o):{success:!1,error:"Server action has no handler or webhookUrl"}}catch(s){let a=s instanceof Error?s.message:String(s);return this.log(`Server action error: ${a}`),{success:false,error:a}}}async executeHandler(e,t){if(!e.handler)return {success:false,error:"No handler defined"};let n=e.timeout??this.config.defaultTimeout;return await Promise.race([e.handler(t,this.context),new Promise((o,s)=>setTimeout(()=>s(new Error("Timeout")),n))])}async executeWebhook(e,t){if(!e.webhookUrl)return {success:false,error:"No webhookUrl defined"};let n=e.timeout??this.config.defaultTimeout,r=e.webhookUrl.startsWith("http")?e.webhookUrl:`${this.config.baseUrl}${e.webhookUrl}`,o={"Content-Type":"application/json",...this.config.webhookHeaders};if(e.webhookSecret){let c=await this.generateSignature(JSON.stringify(t),e.webhookSecret);o["X-Signature"]=c;}this.context&&(o["X-Session-Id"]=this.context.sessionId,this.context.authToken&&(o.Authorization=`Bearer ${this.context.authToken}`));let s=new AbortController,a=setTimeout(()=>s.abort(),n);try{let c=await fetch(r,{method:"POST",headers:o,body:JSON.stringify({actionId:e.id,params:t,context:{sessionId:this.context?.sessionId,userId:this.context?.userId,currentRoute:this.context?.currentRoute}}),signal:s.signal});if(clearTimeout(a),!c.ok)return this.logger.warn("Webhook failed",{actionId:e.id,status:c.status}),{success:!1,error:`Webhook failed with status ${c.status}`};let u=await c.json();return this.logger.debug("Webhook success",{actionId:e.id}),{success:!0,data:u}}catch(c){if(clearTimeout(a),c instanceof Error&&c.name==="AbortError")return {success:false,error:"Request timeout"};throw c}}async generateSignature(e,t){if(typeof crypto>"u"||!crypto.subtle)throw new Error("Web Crypto API (crypto.subtle) is unavailable. Webhook HMAC signing requires a secure context (HTTPS). Either serve the page over HTTPS or remove the webhookSecret.");let n=new TextEncoder,r=await crypto.subtle.importKey("raw",n.encode(t),{name:"HMAC",hash:"SHA-256"},false,["sign"]),o=await crypto.subtle.sign("HMAC",r,n.encode(e));return btoa(String.fromCharCode(...new Uint8Array(o)))}log(...e){this.logger.debug(...e);}};var Ht=z.object({type:z.enum(["click","type","navigate","scroll","select","scan_context","wait_for_dom_stable","wait_for_route","server_action","report_result"]),selector:z.string().max(500).optional(),text:z.string().max(1e3).optional(),value:z.string().max(5e3).optional(),target:z.string().max(1e3).refine(i=>/^\//.test(i)||/^https?:\/\//.test(i),"Only relative paths or http(s) URLs are allowed").optional(),actionId:z.string().max(255).optional(),params:z.record(z.string(),z.unknown()).optional(),context:z.string().max(500).optional()}),Ft=z.object({type:z.literal("command"),batchId:z.string().max(255),commands:z.array(Ht).max(50),message:z.string().max(5e3).optional()}),Ut=z.object({id:z.string(),role:z.enum(["user","assistant","system"]),content:z.string().max(32e3),timestamp:z.number(),status:z.enum(["sending","sent","error"]).optional()}),_e=createLogger("SDK.Storage",{enabled:true,level:"warn"});function zt(i){let e=null;return function(n){typeof window>"u"||(e&&clearTimeout(e),e=setTimeout(()=>{try{let r=n.slice(-100);localStorage.setItem(`${i}-messages`,JSON.stringify(r));}catch(r){_e.warn("Failed to save messages to localStorage",r);try{let o=n.slice(-50);localStorage.setItem(`${i}-messages`,JSON.stringify(o));}catch(o){_e.warn("Failed to save even reduced messages",o);}}},500));}}function qt(i){let e=zt(i);return function(n,r){let o;switch(r.type){case "ADD_MESSAGE":return o={...n,messages:[...n.messages,r.message]},e(o.messages),o;case "UPDATE_MESSAGE":return o={...n,messages:n.messages.map(s=>s.id===r.id?{...s,...r.updates}:s)},e(o.messages),o;case "SET_MESSAGES":return o={...n,messages:r.messages},e(o.messages),o;case "CLEAR_MESSAGES":return o={...n,messages:[]},e([]),o;case "SET_MODE":return {...n,mode:r.mode};case "SET_CONNECTION_STATE":return {...n,connectionState:r.state};case "SET_EXECUTING":return {...n,isExecuting:r.isExecuting};case "SET_EXECUTION_STATE":return {...n,executionState:r.state};case "SET_ERROR":return {...n,error:r.error};case "CLEAR_ERROR":return {...n,error:null};default:return n}}}function Vt(i="chatbot"){let e=[],t="ask";if(typeof window<"u"){try{let r=localStorage.getItem(`${i}-messages`);if(r){let o=JSON.parse(r);Array.isArray(o)?e=o.filter(a=>{let c=Ut.safeParse(a);return c.success||_e.warn("Skipping invalid persisted message",a),c.success}):localStorage.removeItem(`${i}-messages`);}}catch(r){_e.warn("Failed to load messages from localStorage",r);}let n=localStorage.getItem(`${i}-mode`);(n==="ask"||n==="navigate")&&(t=n);}return {messages:e,mode:t,connectionState:"disconnected",isExecuting:false,executionState:null,error:null}}function Kt({apiKey:i,serverUrl:e,navigationAdapter:t,serverActions:n=[],config:r,options:o,routes:s,debug:a$1=false,autoConnect:c=true,children:u}){let h=useMemo(()=>`chatbot-${i.slice(0,8)}`,[i]),E=useMemo(()=>createLogger("SDK",{enabled:a$1,level:"debug"}),[a$1]),S=useMemo(()=>normalizeWidgetConfig(r??void 0),[r]),D=useMemo(()=>{let l={...S};return o?.theme&&(l.theme={...l.theme,...o.theme}),{...l,...o,theme:l.theme}},[S,o]),pe=useMemo(()=>qt(h),[h]),[R,p]=useReducer(pe,h,Vt),me=useRef(R.messages),[J,V]=useState(()=>{if(typeof window<"u"){let l=localStorage.getItem(`${h}-widget-open`);if(l!==null)return l==="true"}return o?.defaultOpen??false}),[te,Pe]=useState(null),$=te??D?.voiceLanguage??void 0,be=useRef(false);useEffect(()=>{if(be.current)return;let l=D.defaultMode;(l==="ask"||l==="navigate")&&(p({type:"SET_MODE",mode:l}),be.current=true);},[D.defaultMode]),useEffect(()=>{typeof window<"u"&&localStorage.setItem(`${h}-widget-open`,String(J));},[J,h]),useEffect(()=>{me.current=R.messages;},[R.messages]),useEffect(()=>{typeof window<"u"&&localStorage.setItem(`${h}-mode`,R.mode);},[R.mode,h]);let A=useRef(null),Q=useRef(null),O=useRef(new Map),G=useRef(null),$e=useRef(null),y=useRef(null),ve=useRef(null),We=useRef(null),F=useRef(null),j=useRef(null),ne=useRef(void 0);useEffect(()=>{ne.current=s;},[s]);let K=useMemo(()=>t??Ze(),[t]);useEffect(()=>{let l=new ce({serverUrl:e,apiKey:i,debug:a$1});return A.current=l,l.on("connected",({sessionId:f})=>{_("Connected, session:",f),p({type:"SET_CONNECTION_STATE",state:"connected"});}),l.on("authenticated",({sessionId:f})=>{let m=j.current,v=K.getCurrentPath();m&&m.setContext({sessionId:f,currentRoute:v});}),l.on("disconnected",()=>{p({type:"SET_CONNECTION_STATE",state:"disconnected"});}),l.on("reconnecting",({attempt:f,maxAttempts:m})=>{_(`Reconnecting ${f}/${m}`),p({type:"SET_CONNECTION_STATE",state:"reconnecting"});}),l.on("reconnect_failed",()=>{p({type:"SET_CONNECTION_STATE",state:"failed"}),p({type:"SET_ERROR",error:new Error("Connection failed")});}),l.on("error",({error:f})=>{p({type:"SET_ERROR",error:f});}),l.on("message",f=>{g.current(f);}),c&&(l.connect(),p({type:"SET_CONNECTION_STATE",state:"connecting"})),()=>{l.destroy(),A.current=null;}},[e,i,a$1,c]),useEffect(()=>{let l=new ke({debug:a$1}),f=new Te({debug:a$1}),m=new Me({debug:a$1}),v=new Ie({debug:a$1}),x=new Oe({debug:a$1});y.current=l,$e.current=f,ve.current=m,We.current=v,j.current=x;let H=b=>{G.current=b,A.current?.send({type:"context",context:b});},C=b=>{x.setContext({sessionId:A.current?.getSessionId()??"",currentRoute:b});},U=()=>{let b=Q.current,B=b?b.getCurrentRoute():typeof window<"u"?window.location.pathname:"/",Ve=f.scan();l.registerDiscoveredActions(B,Ve);let He={...m.build(Ve,l.getServerActions(),B),...s?.length?{routes:s}:{}};return C(He.route),H(He),He},L=new le(K,{debug:a$1,onDOMStable:()=>U()});Q.current=L,L.setScanner(async()=>U());let z=new De(v,L,l,{debug:a$1});F.current=z,z.setServerActionHandler(async(b,B)=>x.execute(b,B));let ae=[];a$1&&(ae.push(z.on("commandStart",(b,B)=>{_("Command start:",{index:B,type:b.type,command:b});})),ae.push(z.on("commandComplete",b=>{_("Command complete:",{type:b.command.type,success:b.success,duration:b.duration,error:b.error});})),ae.push(z.on("complete",b=>{_("Command batch complete:",{total:b.length,failed:b.filter(B=>!B.success).length});})),ae.push(z.on("error",b=>{_("Command processor error:",b);}))),n.forEach(b=>{O.current.set(b.id,b),l.registerServerAction(b),x.register(b);}),f.observe(b=>{l.registerDiscoveredActions(L.getCurrentRoute(),b);let B={...m.build(b,l.getServerActions(),L.getCurrentRoute()),...s?.length?{routes:s}:{}};C(B.route),H(B);});let pt=L.onRouteChange(()=>{C(L.getCurrentRoute()),U();});return typeof window<"u"&&(document.readyState==="complete"?(C(L.getCurrentRoute()),U()):window.addEventListener("load",()=>{C(L.getCurrentRoute()),U();},{once:true})),()=>{f.disconnect(),z.abort(),ae.forEach(b=>b()),pt();}},[K,a$1,s]),useEffect(()=>{let l=y.current,f=j.current;!l||!f||n.forEach(m=>{O.current.set(m.id,m),l.registerServerAction(m),f.register(m);});},[n]);let Z=useRef([]),re=useRef(false),oe=useCallback(async()=>{if(!(re.current||Z.current.length===0)){re.current=true;try{for(;Z.current.length>0;){let l=Z.current.shift();await Be(l.commands,l.batchId);}}finally{re.current=false;}}},[]),ie=useCallback((l,f)=>{Z.current.push({commands:l,batchId:f}),oe();},[oe]),Be=useCallback(async(l,f)=>{let m=F.current;if(!m)return;p({type:"SET_EXECUTING",isExecuting:true});let v=[];v.push(m.on("stateChange",x=>{p({type:"SET_EXECUTION_STATE",state:x}),p({type:"SET_EXECUTING",isExecuting:x.isExecuting});})),v.push(m.on("error",x=>{p({type:"SET_ERROR",error:x});}));try{let x=await m.execute(l),H=A.current;x.forEach(C=>{H&&(C.command.type==="server_action"?H.send({type:"action_result",actionId:C.command.actionId,success:C.success,result:C.result,error:C.error,commandId:f}):H.send({type:"action_result",actionId:C.command.type,success:C.success,error:C.error,commandId:f}));});}catch(x){let H=x instanceof Error?x:new Error(String(x));p({type:"SET_ERROR",error:H});let C=A.current,U=H.message||"Execution failed";l.forEach(L=>{if(!C)return;let z=L.type==="server_action"?L.actionId:L.type;C.send({type:"action_result",actionId:z,success:false,error:U,commandId:f});});}finally{v.forEach(x=>x()),p({type:"SET_EXECUTING",isExecuting:false}),p({type:"SET_EXECUTION_STATE",state:null});}},[]),g=useRef(()=>{}),T=useCallback(l=>{switch(_("Server message received:",l.type,l),l.type){case "response":{let f=me.current.find(v=>v.id===l.messageId);l.isFinal===false?f&&f.role==="assistant"?p({type:"UPDATE_MESSAGE",id:f.id,updates:{content:f.content+l.message,timestamp:Date.now(),status:"sending"}}):p({type:"ADD_MESSAGE",message:{id:l.messageId,role:"assistant",content:l.message,timestamp:Date.now(),status:"sending"}}):f&&f.role==="assistant"?p({type:"UPDATE_MESSAGE",id:f.id,updates:{content:l.message,timestamp:Date.now(),status:"sent"}}):p({type:"ADD_MESSAGE",message:{id:l.messageId,role:"assistant",content:l.message,timestamp:Date.now(),status:"sent"}});}break;case "command":{let f=Ft.safeParse(l);if(!f.success){_("Rejected invalid command message from server:",f.error.issues);break}let m=f.data;_("Received commands:",m.commands);let v=m.commands,x=m.batchId;if(m.message&&p({type:"ADD_MESSAGE",message:{id:createMessageId(),role:"assistant",content:m.message,timestamp:Date.now(),commands:v.length>0?v:void 0}}),v.length===0)break;if(!F.current){p({type:"SET_ERROR",error:new Error("Action runner not ready")}),v.forEach(C=>{let U=C.type==="server_action"?C.actionId:C.type;A.current&&A.current.send({type:"action_result",actionId:U,success:false,error:"Action runner not ready",commandId:x});});break}ie(v,x);break}case "typing":break;case "server_action_result":_("Server action result:",l.actionId,l.result);break;case "error":_("Server error:",l.code,l.error,l.details),p({type:"SET_ERROR",error:new Error(l.error)});break;case "request_context":G.current&&A.current&&A.current.send({type:"context",context:G.current});break}},[ie]);useEffect(()=>{g.current=T;},[T]);let W=useCallback(l=>{let f=createMessageId();_("Sending message:",{messageId:f,mode:R.mode,length:l.length,connectionState:R.connectionState,route:G.current?.route??K.getCurrentPath()}),p({type:"ADD_MESSAGE",message:{id:f,role:"user",content:l,timestamp:Date.now(),status:"sending"}});let m=G.current??{route:K.getCurrentPath(),title:typeof document<"u"?document.title:"",actions:[],serverActions:Array.from(O.current.values()),content:{headings:[],mainContent:"",forms:[]},timestamp:Date.now(),...ne.current?.length?{routes:ne.current}:{}},v=te??D?.voiceLanguage??void 0;A.current?.send({type:"message",content:l,context:m,mode:R.mode,messageId:f,...v!=null?{locale:v}:{}}),p({type:"UPDATE_MESSAGE",id:f,updates:{status:"sent"}});},[R.mode,K,te,D?.voiceLanguage]),ye=useCallback(l=>{Pe(l??null);},[]),xe=useCallback(l=>{p({type:"SET_MODE",mode:l});},[]),Ee=useCallback(async(l,f)=>{let m=j.current;if(!m)throw new Error("Server action bridge not ready");if(!m.getAction(l)){let x=O.current.get(l);x&&m.register(x);}let v=await m.execute(l,f??{});return A.current&&A.current.send({type:"action_result",actionId:l,success:v.success,result:v.data,error:v.error}),v},[]),Se=useCallback(l=>{O.current.set(l.id,l),y.current?.registerServerAction(l),j.current?.register(l),E.debug("Registered server action:",l.id);},[E]),we=useCallback(()=>{p({type:"CLEAR_MESSAGES"});},[]),se=useCallback(()=>{p({type:"CLEAR_ERROR"});},[]),Ce=useCallback(()=>{F.current?.abort();},[]),Re=useCallback(()=>{p({type:"SET_CONNECTION_STATE",state:"connecting"}),A.current?.connect();},[]),Ae=useCallback(()=>{A.current?.disconnect(),p({type:"SET_CONNECTION_STATE",state:"disconnected"});},[]);function _(...l){E.debug(...l);}let ee=useMemo(()=>({widgetConfig:D,messages:R.messages,mode:R.mode,connectionState:R.connectionState,isExecuting:R.isExecuting,executionState:R.executionState,error:R.error,isWidgetOpen:J,setWidgetOpen:V,voiceLanguage:$,setVoiceLanguage:ye,sendMessage:W,setMode:xe,executeAction:Ee,registerServerAction:Se,clearMessages:we,clearError:se,stopExecution:Ce,connect:Re,disconnect:Ae,isConnected:R.connectionState==="connected"}),[D,R,J,$,ye,W,xe,Ee,Se,we,se,Ce,Re,Ae]);return jsx(a.Provider,{value:ee,children:u})}var dt=`
|
|
2
2
|
/* =============================================
|
|
3
3
|
Navsi Chatbot Widget \u2014 Base Styles
|
|
4
4
|
============================================= */
|
|
@@ -544,5 +544,5 @@ import {a,c,d,e,f}from'./chunk-UWRZ4ZYG.js';import qe,{useMemo,useReducer,useRef
|
|
|
544
544
|
${f?"bottom: 24px; top: auto;":"top: 24px; bottom: auto;"}
|
|
545
545
|
${l?"right: 24px; left: auto;":"left: 24px; right: auto;"}
|
|
546
546
|
}
|
|
547
|
-
`;},[$?.theme]);let ne={position:"fixed",zIndex:9999},K=$?.headerTitle??"AI Assistant",Z=$?.welcomeMessage??"How can I help you today?",re=$?.subtitle??"Type a message to get started",oe=$?.askPlaceholder??"Ask a question...",ie=$?.navigatePlaceholder??"What should I do? Try: Go to cart, Add product 1 to cart",Be=$?.supportedLanguages??[{code:"en-US",label:"EN"},{code:"hi-IN",label:"\u0939\u093F\u0902\u0926\u0940"}];return jsxs("div",{style:ne,className:`navsi-chatbot-container ${i||""}`,children:[V&&jsxs("div",{className:`navsi-chatbot-window ${e$1||""}`,children:[jsxs("div",{className:"navsi-chatbot-header",children:[jsx("div",{className:"navsi-chatbot-header-left",children:jsxs("div",{children:[jsx("div",{className:"navsi-chatbot-title",children:K}),jsx("div",{className:"navsi-chatbot-status",children:S?"Connected":G?"Reconnecting":"Disconnected"}),y.isListening&&jsxs("div",{className:"navsi-chatbot-voice-indicator","aria-live":"polite",children:[jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("path",{d:"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"}),jsx("path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}),jsx("line",{x1:"12",y1:"19",x2:"12",y2:"23"}),jsx("line",{x1:"8",y1:"23",x2:"16",y2:"23"})]}),"Listening\u2026"]})]})}),jsxs("div",{className:"navsi-chatbot-mode-toggle",children:[jsx("button",{className:`navsi-chatbot-mode-button ${D==="ask"?"navsi-chatbot-mode-active":""}`,onClick:()=>pe("ask"),children:"Ask"}),jsx("button",{className:`navsi-chatbot-mode-button ${D==="navigate"?"navsi-chatbot-mode-active":""}`,onClick:()=>pe("navigate"),children:"Action"})]}),jsx("div",{className:"navsi-chatbot-lang-toggle",role:"group","aria-label":"Voice and response language",children:Be.map(g=>jsx("button",{type:"button",className:`navsi-chatbot-lang-button ${Q.startsWith(g.code.split("-")[0])?"navsi-chatbot-lang-active":""}`,onClick:()=>A(g.code),title:g.label,"aria-pressed":Q.startsWith(g.code.split("-")[0]),children:g.label},g.code))}),h.length>0&&jsx("button",{type:"button",onClick:()=>J(),className:"navsi-chatbot-clear",title:"Clear chat","aria-label":"Clear chat",children:"Clear"})]}),R&&jsxs("div",{className:"navsi-chatbot-banner",children:[jsx("span",{children:"\u26A1 Executing actions\u2026"}),O&&jsxs(Fragment,{children:[jsxs("span",{className:"navsi-chatbot-pill",children:[O.current+1,"/",O.total]}),O.description&&jsx("span",{className:"navsi-chatbot-step",children:O.description})]})]}),O&&jsx("div",{className:"navsi-chatbot-progress-container",children:jsx("div",{className:"navsi-chatbot-progress-bar",children:jsx("div",{className:"navsi-chatbot-progress-fill",style:{width:`${O.percentage??0}%`}})})}),p&&jsxs("div",{className:"navsi-chatbot-error",children:[jsx("span",{children:p.message}),jsx("button",{className:"navsi-chatbot-error-close",onClick:me,children:"\u2715"})]}),y.error&&jsx("div",{className:"navsi-chatbot-voice-error",role:"alert",children:y.error}),jsxs("div",{ref:s,className:"navsi-chatbot-messages",role:"log","aria-live":"polite","aria-label":"Chat messages",children:[h.length===0&&jsxs("div",{className:"navsi-chatbot-welcome",children:[jsx("div",{className:"navsi-chatbot-welcome-icon",children:"\u{1F44B}"}),jsx("div",{className:"navsi-chatbot-welcome-text",children:Z}),jsx("div",{className:"navsi-chatbot-welcome-hint",children:re})]}),h.map(g=>jsx("div",{className:`navsi-chatbot-message ${g.role==="user"?"navsi-chatbot-message-user":"navsi-chatbot-message-assistant"}`,children:jsx(Yt,{content:g.content,isUser:g.role==="user"})},g.id)),jsx("div",{ref:o})]}),jsxs("div",{className:"navsi-chatbot-input-area",children:[jsx("input",{type:"text",value:n,onChange:g=>r(g.target.value),onKeyDown:We,placeholder:D==="ask"?oe:ie,className:"navsi-chatbot-input",maxLength:8e3,"aria-label":D==="ask"?oe:ie}),jsx("button",{className:`navsi-chatbot-voice-button ${y.isListening?"navsi-chatbot-voice-button-active":""}`,onClick:()=>{y.isListening?y.stop():y.start();},disabled:!S||!y.isSupported,"aria-label":y.isSupported?y.isListening?"Stop voice input":"Start voice input":"Voice input not supported in this browser","aria-pressed":y.isListening,title:y.isSupported?y.isListening?"Click to stop and send":"Click to start listening":"Voice input is not available in this browser",type:"button",children:y.isListening?jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("circle",{cx:"12",cy:"12",r:"8"})}):jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("path",{d:"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"}),jsx("path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}),jsx("line",{x1:"12",y1:"19",x2:"12",y2:"23"}),jsx("line",{x1:"8",y1:"23",x2:"16",y2:"23"})]})}),R?jsx("button",{className:"navsi-chatbot-stop-button",onClick:Pe,"aria-label":"Stop",title:"Stop current action",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1"})})}):jsx("button",{className:"navsi-chatbot-send-button",onClick:ve,disabled:!S,children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"})})})]}),y.transcript&&jsx("div",{className:"navsi-chatbot-voice-transcript","aria-live":"polite",children:y.transcript})]}),jsx("button",{className:`navsi-chatbot-toggle ${t||""}`,onClick:()=>te(!V),"aria-label":V?"Close chat":"Open chat",children:V?jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"})}):jsx("svg",{width:"28",height:"28",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"})})})]})}export{ce as a,en as b,Ze as c,le as d,on as e,Kt as f,Jt as g};//# sourceMappingURL=chunk-
|
|
548
|
-
//# sourceMappingURL=chunk-
|
|
547
|
+
`;},[$?.theme]);let ne={position:"fixed",zIndex:9999},K=$?.headerTitle??"AI Assistant",Z=$?.welcomeMessage??"How can I help you today?",re=$?.subtitle??"Type a message to get started",oe=$?.askPlaceholder??"Ask a question...",ie=$?.navigatePlaceholder??"What should I do? Try: Go to cart, Add product 1 to cart",Be=$?.supportedLanguages??[{code:"en-US",label:"EN"},{code:"hi-IN",label:"\u0939\u093F\u0902\u0926\u0940"}];return jsxs("div",{style:ne,className:`navsi-chatbot-container ${i||""}`,children:[V&&jsxs("div",{className:`navsi-chatbot-window ${e$1||""}`,children:[jsxs("div",{className:"navsi-chatbot-header",children:[jsx("div",{className:"navsi-chatbot-header-left",children:jsxs("div",{children:[jsx("div",{className:"navsi-chatbot-title",children:K}),jsx("div",{className:"navsi-chatbot-status",children:S?"Connected":G?"Reconnecting":"Disconnected"}),y.isListening&&jsxs("div",{className:"navsi-chatbot-voice-indicator","aria-live":"polite",children:[jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("path",{d:"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"}),jsx("path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}),jsx("line",{x1:"12",y1:"19",x2:"12",y2:"23"}),jsx("line",{x1:"8",y1:"23",x2:"16",y2:"23"})]}),"Listening\u2026"]})]})}),jsxs("div",{className:"navsi-chatbot-mode-toggle",children:[jsx("button",{className:`navsi-chatbot-mode-button ${D==="ask"?"navsi-chatbot-mode-active":""}`,onClick:()=>pe("ask"),children:"Ask"}),jsx("button",{className:`navsi-chatbot-mode-button ${D==="navigate"?"navsi-chatbot-mode-active":""}`,onClick:()=>pe("navigate"),children:"Action"})]}),jsx("div",{className:"navsi-chatbot-lang-toggle",role:"group","aria-label":"Voice and response language",children:Be.map(g=>jsx("button",{type:"button",className:`navsi-chatbot-lang-button ${Q.startsWith(g.code.split("-")[0])?"navsi-chatbot-lang-active":""}`,onClick:()=>A(g.code),title:g.label,"aria-pressed":Q.startsWith(g.code.split("-")[0]),children:g.label},g.code))}),h.length>0&&jsx("button",{type:"button",onClick:()=>J(),className:"navsi-chatbot-clear",title:"Clear chat","aria-label":"Clear chat",children:"Clear"})]}),R&&jsxs("div",{className:"navsi-chatbot-banner",children:[jsx("span",{children:"\u26A1 Executing actions\u2026"}),O&&jsxs(Fragment,{children:[jsxs("span",{className:"navsi-chatbot-pill",children:[O.current+1,"/",O.total]}),O.description&&jsx("span",{className:"navsi-chatbot-step",children:O.description})]})]}),O&&jsx("div",{className:"navsi-chatbot-progress-container",children:jsx("div",{className:"navsi-chatbot-progress-bar",children:jsx("div",{className:"navsi-chatbot-progress-fill",style:{width:`${O.percentage??0}%`}})})}),p&&jsxs("div",{className:"navsi-chatbot-error",children:[jsx("span",{children:p.message}),jsx("button",{className:"navsi-chatbot-error-close",onClick:me,children:"\u2715"})]}),y.error&&jsx("div",{className:"navsi-chatbot-voice-error",role:"alert",children:y.error}),jsxs("div",{ref:s,className:"navsi-chatbot-messages",role:"log","aria-live":"polite","aria-label":"Chat messages",children:[h.length===0&&jsxs("div",{className:"navsi-chatbot-welcome",children:[jsx("div",{className:"navsi-chatbot-welcome-icon",children:"\u{1F44B}"}),jsx("div",{className:"navsi-chatbot-welcome-text",children:Z}),jsx("div",{className:"navsi-chatbot-welcome-hint",children:re})]}),h.map(g=>jsx("div",{className:`navsi-chatbot-message ${g.role==="user"?"navsi-chatbot-message-user":"navsi-chatbot-message-assistant"}`,children:jsx(Yt,{content:g.content,isUser:g.role==="user"})},g.id)),jsx("div",{ref:o})]}),jsxs("div",{className:"navsi-chatbot-input-area",children:[jsx("input",{type:"text",value:n,onChange:g=>r(g.target.value),onKeyDown:We,placeholder:D==="ask"?oe:ie,className:"navsi-chatbot-input",maxLength:8e3,"aria-label":D==="ask"?oe:ie}),jsx("button",{className:`navsi-chatbot-voice-button ${y.isListening?"navsi-chatbot-voice-button-active":""}`,onClick:()=>{y.isListening?y.stop():y.start();},disabled:!S||!y.isSupported,"aria-label":y.isSupported?y.isListening?"Stop voice input":"Start voice input":"Voice input not supported in this browser","aria-pressed":y.isListening,title:y.isSupported?y.isListening?"Click to stop and send":"Click to start listening":"Voice input is not available in this browser",type:"button",children:y.isListening?jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("circle",{cx:"12",cy:"12",r:"8"})}):jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("path",{d:"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"}),jsx("path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}),jsx("line",{x1:"12",y1:"19",x2:"12",y2:"23"}),jsx("line",{x1:"8",y1:"23",x2:"16",y2:"23"})]})}),R?jsx("button",{className:"navsi-chatbot-stop-button",onClick:Pe,"aria-label":"Stop",title:"Stop current action",children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1"})})}):jsx("button",{className:"navsi-chatbot-send-button",onClick:ve,disabled:!S,children:jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"})})})]}),y.transcript&&jsx("div",{className:"navsi-chatbot-voice-transcript","aria-live":"polite",children:y.transcript})]}),jsx("button",{className:`navsi-chatbot-toggle ${t||""}`,onClick:()=>te(!V),"aria-label":V?"Close chat":"Open chat",children:V?jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"})}):jsx("svg",{width:"28",height:"28",viewBox:"0 0 24 24",fill:"currentColor",children:jsx("path",{d:"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"})})})]})}export{ce as a,en as b,Ze as c,le as d,on as e,Kt as f,Jt as g};//# sourceMappingURL=chunk-MORKY4MY.js.map
|
|
548
|
+
//# sourceMappingURL=chunk-MORKY4MY.js.map
|