@ourguide-ai/client 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function q(e){return new Promise((t,s)=>{const n=new FileReader;n.onload=()=>{const r=n.result;t(r.split(",")[1])},n.onerror=()=>s(new Error("Failed to read file")),n.readAsDataURL(e)})}async function W(e,t){const s=`${e}/api/products/${t}/config`;console.log("[Ourguide] fetchConfig HTTP GET",s);try{const n=await fetch(s,{headers:{"ngrok-skip-browser-warning":"true"}});if(console.log("[Ourguide] fetchConfig HTTP status:",n.status,n.statusText),!n.ok)return console.warn("[Ourguide] fetchConfig non-OK response, returning {}"),{};const r=await n.json();return console.log("[Ourguide] fetchConfig raw JSON:",JSON.stringify(r,null,2)),r}catch(n){return console.error("[Ourguide] fetchConfig threw:",n),{}}}async function M(e,t,s,n,r,o){const i={productId:t,messages:s,endUserSessionId:n};r&&(i.conversationId=r),o&&o.length>0&&(i.attachments=o);const l=await fetch(`${e}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json","ngrok-skip-browser-warning":"true"},body:JSON.stringify(i)});if(!l.ok){const a=await l.json().catch(()=>({error:"Request failed"}));throw new Error(a.error||`HTTP ${l.status}`)}if(!l.body)throw new Error("No response stream available");return{stream:l.body,conversationId:l.headers.get("X-Conversation-Id")}}async function K(e,t,s,n,r){const o=await fetch(`${e}/api/widget/identify`,{method:"POST",headers:{"Content-Type":"application/json","ngrok-skip-browser-warning":"true"},body:JSON.stringify({productId:t,endUserSessionId:s,token:n,name:r})}),i=await o.json().catch(()=>({}));if(!o.ok)throw new Error(i.error||`HTTP ${o.status}`);return i}async function Y(e,t,s){const n=await fetch(`${e}/api/widget/reset-user`,{method:"POST",headers:{"Content-Type":"application/json","ngrok-skip-browser-warning":"true"},body:JSON.stringify({productId:t,endUserSessionId:s})}),r=await n.json().catch(()=>({}));if(!n.ok)throw new Error(r.error||`HTTP ${n.status}`);return r}const Q={isOpen:!1,messages:[],isStreaming:!1,error:null};function L(){return Date.now().toString(36)+Math.random().toString(36).slice(2,7)}function Z(e,t){var s;switch(t.type){case"OPEN":return{...e,isOpen:!0,error:null};case"CLOSE":return{...e,isOpen:!1};case"LOAD_MESSAGES":return{...e,messages:t.messages};case"ADD_USER_MESSAGE":return{...e,error:null,messages:[...e.messages,{id:t.id,role:"user",content:t.content}]};case"START_STREAMING":return{...e,isStreaming:!0,error:null,messages:[...e.messages,{id:t.id,role:"assistant",content:"",isStreaming:!0}]};case"APPEND_TEXT":{const n=[...e.messages],r=n[n.length-1];return r&&r.role==="assistant"&&r.isStreaming&&(n[n.length-1]={...r,content:r.content+t.text}),{...e,messages:n}}case"ADD_TOOL_CALL":{const n=[...e.messages],r=n[n.length-1];if(r&&r.role==="assistant"){const o=[...r.toolCalls??[],t.toolCall];n[n.length-1]={...r,toolCalls:o}}return{...e,messages:n}}case"SET_TOOL_RESULT":{const n=[...e.messages],r=n[n.length-1];if(r&&r.role==="assistant"&&r.toolCalls){const o=r.toolCalls.map(i=>i.id===t.toolCallId?{...i,result:t.result,status:"done"}:i);n[n.length-1]={...r,toolCalls:o}}return{...e,messages:n}}case"FINISH_STREAMING":{const n=[...e.messages],r=n[n.length-1];return r&&r.role==="assistant"&&r.isStreaming&&(!r.content&&((s=r.toolCalls)!=null&&s.length)?n.pop():n[n.length-1]={...r,isStreaming:!1}),{...e,isStreaming:!1,messages:n}}case"SET_ERROR":{const n=[...e.messages],r=n[n.length-1];return r&&r.role==="assistant"&&r.isStreaming&&(n[n.length-1]={...r,isStreaming:!1}),{...e,isStreaming:!1,error:t.error,messages:n}}case"CLEAR_MESSAGES":return{...e,messages:[],error:null,isStreaming:!1};default:return e}}async function D(e,t){const s=e.getReader(),n=new TextDecoder;let r="";try{for(;;){const{done:o,value:i}=await s.read();if(r+=o?n.decode():n.decode(i,{stream:!0}),o)break;const l=r.split(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function W(e){return new Promise((t,s)=>{const n=new FileReader;n.onload=()=>{const r=n.result;t(r.split(",")[1])},n.onerror=()=>s(new Error("Failed to read file")),n.readAsDataURL(e)})}async function K(e,t){const s=`${e}/api/products/${t}/config`;console.log("[Ourguide] fetchConfig HTTP GET",s);try{const n=await fetch(s,{headers:{"ngrok-skip-browser-warning":"true"}});if(console.log("[Ourguide] fetchConfig HTTP status:",n.status,n.statusText),!n.ok)return console.warn("[Ourguide] fetchConfig non-OK response, returning {}"),{};const r=await n.json();return console.log("[Ourguide] fetchConfig raw JSON:",JSON.stringify(r,null,2)),r}catch(n){return console.error("[Ourguide] fetchConfig threw:",n),{}}}async function M(e,t,s,n,r,o,i){const l={productId:t,messages:s,endUserSessionId:n};r&&(l.conversationId=r),o&&o.length>0&&(l.attachments=o);const a=await fetch(`${e}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json","ngrok-skip-browser-warning":"true"},body:JSON.stringify(l),signal:i});if(!a.ok){const S=await a.json().catch(()=>({error:"Request failed"}));throw new Error(S.error||`HTTP ${a.status}`)}if(!a.body)throw new Error("No response stream available");return{stream:a.body,conversationId:a.headers.get("X-Conversation-Id")}}async function Y(e,t,s,n,r){const o=await fetch(`${e}/api/widget/identify`,{method:"POST",headers:{"Content-Type":"application/json","ngrok-skip-browser-warning":"true"},body:JSON.stringify({productId:t,endUserSessionId:s,token:n,name:r})}),i=await o.json().catch(()=>({}));if(!o.ok)throw new Error(i.error||`HTTP ${o.status}`);return i}async function Q(e,t,s){const n=await fetch(`${e}/api/widget/reset-user`,{method:"POST",headers:{"Content-Type":"application/json","ngrok-skip-browser-warning":"true"},body:JSON.stringify({productId:t,endUserSessionId:s})}),r=await n.json().catch(()=>({}));if(!n.ok)throw new Error(r.error||`HTTP ${n.status}`);return r}const Z={isOpen:!1,messages:[],isStreaming:!1,error:null};function L(){return Date.now().toString(36)+Math.random().toString(36).slice(2,7)}function tt(e,t){var s;switch(t.type){case"OPEN":return{...e,isOpen:!0,error:null};case"CLOSE":return{...e,isOpen:!1};case"LOAD_MESSAGES":return{...e,messages:t.messages};case"ADD_USER_MESSAGE":return{...e,error:null,messages:[...e.messages,{id:t.id,role:"user",content:t.content}]};case"START_STREAMING":return{...e,isStreaming:!0,error:null,messages:[...e.messages,{id:t.id,role:"assistant",content:"",isStreaming:!0}]};case"APPEND_TEXT":{const n=[...e.messages],r=n[n.length-1];return r&&r.role==="assistant"&&r.isStreaming&&(n[n.length-1]={...r,content:r.content+t.text}),{...e,messages:n}}case"ADD_TOOL_CALL":{const n=[...e.messages],r=n[n.length-1];if(r&&r.role==="assistant"){const o=[...r.toolCalls??[],t.toolCall];n[n.length-1]={...r,toolCalls:o}}return{...e,messages:n}}case"SET_TOOL_RESULT":{const n=[...e.messages],r=n[n.length-1];if(r&&r.role==="assistant"&&r.toolCalls){const o=r.toolCalls.map(i=>i.id===t.toolCallId?{...i,result:t.result,status:"done"}:i);n[n.length-1]={...r,toolCalls:o}}return{...e,messages:n}}case"FINISH_STREAMING":{const n=[...e.messages],r=n[n.length-1];return r&&r.role==="assistant"&&r.isStreaming&&(!r.content&&((s=r.toolCalls)!=null&&s.length)?n.pop():n[n.length-1]={...r,isStreaming:!1}),{...e,isStreaming:!1,messages:n}}case"SET_ERROR":{const n=[...e.messages],r=n[n.length-1];return r&&r.role==="assistant"&&r.isStreaming&&(n[n.length-1]={...r,isStreaming:!1}),{...e,isStreaming:!1,error:t.error,messages:n}}case"CLEAR_MESSAGES":return{...e,messages:[],error:null,isStreaming:!1};default:return e}}async function D(e,t){const s=e.getReader(),n=new TextDecoder;let r="";try{for(;;){const{done:o,value:i}=await s.read();if(r+=o?n.decode():n.decode(i,{stream:!0}),o)break;const l=r.split(`
2
2
 
3
- `);r=l.pop()??"";for(const a of l)z(a.trim(),t)}r.trim()&&z(r.trim(),t),t.onFinish()}catch(o){const i=o instanceof Error?o.message:"Stream read failed";t.onError(i)}finally{s.releaseLock()}}function z(e,t){const s=e.split(`
4
- `);for(const n of s){if(!n.startsWith("data: "))continue;const r=n.slice(6);if(r==="[DONE]")return;try{const o=JSON.parse(r);switch(o.type){case"text-delta":o.delta&&t.onTextDelta(o.delta);break;case"tool-input-available":o.toolCallId&&o.toolName&&t.onToolCall(o.toolCallId,o.toolName,o.input??{},o.providerMetadata);break;case"tool-output-available":o.toolCallId&&t.onToolResult(o.toolCallId,o.output);break;case"tool-call":o.toolCallId&&o.toolName&&t.onToolCall(o.toolCallId,o.toolName,o.input??{});break;case"tool-result":o.toolCallId&&t.onToolResult(o.toolCallId,o.output);break;case"error":t.onError(o.errorText??o.reason??"Unknown error");break;case"abort":t.onError(o.reason??"Response aborted");break;default:break}}catch{}}}const H={};function U(e){Object.assign(H,e)}function tt(e){return H[e]}function et(e){return Object.hasOwn(H,e)}const dt="og2-chat-",gt="og2-enduser-session-",j="og2-conv-";function B(e){return`${dt}${e}`}function nt(e){return`${gt}${e}`}function X(){var t,s;const e=(s=(t=globalThis.crypto)==null?void 0:t.randomUUID)==null?void 0:s.call(t);return e||`${Date.now()}-${Math.random().toString(16).slice(2)}`}function _(e){const t=nt(e);try{const s=localStorage.getItem(t);if(s&&s.trim())return s;const n=`sess_${X()}`;return localStorage.setItem(t,n),n}catch{return`sess_${X()}`}}function st(e){try{localStorage.removeItem(nt(e))}catch{}}function rt(e,t){try{const s=t.map(({isStreaming:n,...r})=>r);sessionStorage.setItem(B(e),JSON.stringify(s))}catch{}}function ot(e){try{const t=sessionStorage.getItem(B(e));return t?JSON.parse(t):[]}catch{return[]}}function P(e){try{sessionStorage.removeItem(B(e)),sessionStorage.removeItem(`${j}${e}`)}catch{}}function it(e,t){try{sessionStorage.setItem(`${j}${e}`,t)}catch{}}function at(e){try{return sessionStorage.getItem(`${j}${e}`)}catch{return null}}const ht=10,pt=30,N=500,ft="og2-widget-root",mt=new Set(["SCRIPT","STYLE","NOSCRIPT","SVG","NAV","HEADER","FOOTER"]),St="a[href], button, input, select, textarea";function x(e){if(!(e instanceof HTMLElement))return!1;if(typeof e.checkVisibility=="function")return e.checkVisibility({checkOpacity:!1,checkVisibilityCSS:!0});let t=e;for(;t;){if(t.hidden||t.getAttribute("aria-hidden")==="true")return!1;const s=getComputedStyle(t);if(s.display==="none"||s.visibility==="hidden")return!1;t=t.parentElement}return!0}function A(e){return!!e.closest(`#${ft}`)}function yt(e){var s,n;if(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement){if(e.id){const r=document.querySelector(`label[for="${CSS.escape(e.id)}"]`);if((s=r==null?void 0:r.textContent)!=null&&s.trim())return r.textContent.trim()}return e.getAttribute("aria-label")||e.placeholder||e.getAttribute("name")||""}const t=(n=e.innerText)==null?void 0:n.trim();return t||e.getAttribute("aria-label")||e.getAttribute("title")||""}function V(e,t){return e.length<=t?e:e.slice(0,t-3)+"..."}function ct(){var w;const e=window.location.pathname+window.location.search,t=document.title||"",s=document.querySelectorAll("h1, h2, h3"),n=[];for(const c of s){if(n.length>=ht)break;if(A(c)||!x(c))continue;const g=(w=c.innerText)==null?void 0:w.trim();g&&!n.includes(g)&&n.push(g)}const r=document.querySelectorAll(St),o=[],i=new Set;for(const c of r){if(o.length>=pt)break;if(A(c)||!x(c))continue;const g=yt(c);if(!g)continue;const E=`${c.tagName}:${g}`;if(i.has(E))continue;i.add(E);const m={tag:c.tagName.toLowerCase(),text:V(g,80)};if(c instanceof HTMLInputElement&&(m.type=c.type),c instanceof HTMLAnchorElement&&c.href)try{const C=new URL(c.href);m.href=C.pathname+C.search}catch{m.href=c.getAttribute("href")||void 0}o.push(m)}const l=document.querySelector("main")||document.body;let a="";function T(c){var E;if(a.length>=N)return;if(c.nodeType===Node.TEXT_NODE){const m=(E=c.textContent)==null?void 0:E.trim();m&&(a+=(a?" ":"")+m);return}if(c.nodeType!==Node.ELEMENT_NODE)return;const g=c;if(!mt.has(g.tagName)&&!A(g)&&x(g)){for(const m of g.childNodes)if(T(m),a.length>=N)return}}return T(l),a=V(a.replace(/\s+/g," ").trim(),N),{url:e,title:t,headings:n,interactiveElements:o,visibleText:a}}function Et(e,t){if(!t)return e;let s=e;for(const[n,r]of Object.entries(t)){const o=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");s=s.replace(new RegExp(`:${o}(?!\\w)`,"g"),encodeURIComponent(r))}return s}function It(e){var n;const t=e.replace(/\/$/,"")||"/",s=document.querySelectorAll("a[href]");for(const r of s){const o=r,i=((n=o.pathname)==null?void 0:n.replace(/\/$/,""))||"/";if(o.origin===window.location.origin&&i===t)return o.click(),console.log(`[Ourguide] Navigated via anchor click: ${e}`),!0}return!1}function Tt(e){var r,o;const t=window,s=t.next;if((r=s==null?void 0:s.router)!=null&&r.push)return s.router.push(e),console.log(`[Ourguide] Navigated via Next.js router: ${e}`),!0;if(t.__NUXT__){const i=t.$nuxt;if((o=i==null?void 0:i.$router)!=null&&o.push)return i.$router.push(e),console.log(`[Ourguide] Navigated via Vue/Nuxt router: ${e}`),!0}return!1}function bt(e){try{return window.history.pushState({},"",e),window.dispatchEvent(new PopStateEvent("popstate",{state:{}})),console.log(`[Ourguide] Navigated via pushState: ${e}`),!0}catch{return!1}}async function lt(e,t,s){const n=Et(e,t);return s?(s(n),console.log(`[Ourguide] Navigated via navigate prop: ${n}`),!0):(It(n)||Tt(n)||bt(n)||(console.log(`[Ourguide] Navigated via hard navigation: ${n}`),window.location.href=n),!0)}class wt{constructor(t){this.state=Q,this.conversationId=null,this.callbacks={},this.productId=t.productId,this.apiUrl=t.apiUrl,this.conversationId=at(this.productId);const s=ot(this.productId);s.length>0&&this.dispatch({type:"LOAD_MESSAGES",messages:s}),U({capture_screen:async()=>ct()})}on(t){this.callbacks={...this.callbacks,...t}}getState(){return this.state}getMessages(){return this.state.messages}dispatch(t){var s,n;this.state=Z(this.state,t),(n=(s=this.callbacks).onStateChange)==null||n.call(s,this.state)}open(){this.dispatch({type:"OPEN"})}close(){this.dispatch({type:"CLOSE"})}registerTools(t){U(t)}async loadConfig(){var s,n;const t=await W(this.apiUrl,this.productId);return(n=(s=this.callbacks).onConfigLoaded)==null||n.call(s,t),t}async identify(t,s){const n=_(this.productId);await K(this.apiUrl,this.productId,n,t,s)}resetUser(){const t=_(this.productId);Y(this.apiUrl,this.productId,t).catch(()=>{}),st(this.productId),P(this.productId),this.conversationId=null,this.dispatch({type:"FINISH_STREAMING"}),this.dispatch({type:"CLEAR_MESSAGES"})}newConversation(){const t=this.state.messages;let s=null;if(t.length>0){const n=t.find(r=>r.role==="user");s={title:n?n.content.slice(0,30):"Conversation",preview:t[t.length-1].content.slice(0,50),messages:[...t]}}return P(this.productId),this.conversationId=null,this.dispatch({type:"CLEAR_MESSAGES"}),s}async sendMessage(t,s,n){var E,m,C,G;const r=t.trim(),o=s?[...s]:[];if(!r&&o.length===0||this.state.isStreaming)return;const i=o.length>0?o.map(h=>`[${h.name}]`).join(" "):"",l=[r,i].filter(Boolean).join(" ");this.dispatch({type:"ADD_USER_MESSAGE",id:L(),content:l});let a=[];if(o.length>0)try{a=await Promise.all(o.map(async h=>({name:h.name,type:h.type,data:await q(h)})))}catch{this.dispatch({type:"SET_ERROR",error:"Failed to read attached files"});return}const T=[...this.state.messages.map(h=>({role:h.role,content:h.content})),{role:"user",content:r||"Please review the attached file(s)."}];this.dispatch({type:"START_STREAMING",id:L()});const w=new Map,c=new Map,g=h=>({onTextDelta:d=>this.dispatch({type:"APPEND_TEXT",text:d}),onToolCall:(d,f,p,S)=>{var y,u;const I={id:d,name:f,args:p,status:"calling",providerMetadata:S};w.set(d,I),this.dispatch({type:"ADD_TOOL_CALL",toolCall:I}),(u=(y=this.callbacks).onToolCall)==null||u.call(y,I),h&&et(f)&&c.set(d,{name:f,args:p,providerMetadata:S})},onToolResult:(d,f)=>{var S,I;this.dispatch({type:"SET_TOOL_RESULT",toolCallId:d,result:f});const p=w.get(d);if(p&&((I=(S=this.callbacks).onToolResult)==null||I.call(S,p.name,f)),(p==null?void 0:p.name)==="navigate_to_page"){const y=f;y.route&&(y.confidence??0)>=.5&&lt(y.route,y.params,n)}},onError:d=>{var f,p;this.dispatch({type:"SET_ERROR",error:d}),(p=(f=this.callbacks).onError)==null||p.call(f,d)}});try{const h=_(this.productId),{stream:d,conversationId:f}=await M(this.apiUrl,this.productId,T,h,this.conversationId||void 0,a);f&&!this.conversationId&&(this.conversationId=f,it(this.productId,f));let p=!1;if(await D(d,{...g(!0),onError:u=>{var $,v;p=!0,this.dispatch({type:"SET_ERROR",error:u}),(v=($=this.callbacks).onError)==null||v.call($,u)},onFinish:()=>{}}),p||c.size===0){p||this.dispatch({type:"FINISH_STREAMING"}),this.persistMessages();return}const S=[];for(const[u,{name:$,args:v,providerMetadata:ut}]of c){let O;try{O=await tt($)(v)}catch(F){O={status:"error",error:F instanceof Error?F.message:"Handler failed"}}this.dispatch({type:"SET_TOOL_RESULT",toolCallId:u,result:O}),(m=(E=this.callbacks).onToolResult)==null||m.call(E,$,O),S.push({toolCallId:u,toolName:$,args:v,result:O,providerMetadata:ut})}const I=[...T,{role:"assistant",content:S.map(u=>({type:"tool-call",toolCallId:u.toolCallId,toolName:u.toolName,input:u.args,...u.providerMetadata?{providerOptions:u.providerMetadata}:{}}))},{role:"tool",content:S.map(u=>({type:"tool-result",toolCallId:u.toolCallId,toolName:u.toolName,output:{type:"json",value:u.result}}))}],{stream:y}=await M(this.apiUrl,this.productId,I,void 0,this.conversationId||void 0);await D(y,{...g(!1),onFinish:()=>this.dispatch({type:"FINISH_STREAMING"})})}catch(h){this.dispatch({type:"FINISH_STREAMING"});const d=h instanceof Error?h.message:"Something went wrong";this.dispatch({type:"SET_ERROR",error:d}),(G=(C=this.callbacks).onError)==null||G.call(C,d)}this.persistMessages()}persistMessages(){!this.state.isStreaming&&this.state.messages.length>0&&rt(this.productId,this.state.messages)}}function k(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function b(e){let t=e;return t=t.replace(/`([^`\n]+)`/g,'<code class="og2-md-inline-code">$1</code>'),t=t.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),t=t.replace(/__(.+?)__/g,"<strong>$1</strong>"),t=t.replace(/\*(.+?)\*/g,"<em>$1</em>"),t=t.replace(new RegExp("(?<!\\w)_(.+?)_(?!\\w)","g"),"<em>$1</em>"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(s,n,r)=>{const o=r.trim();return/^(https?:\/\/|mailto:|\/|#)/i.test(o)?`<a class="og2-md-link" href="${o}" target="_blank" rel="noopener noreferrer">${n}</a>`:n}),t}function $t(e){if(!e)return"";const t=[];let s=e.replace(/```(\w*)\n([\s\S]*?)```/g,(n,r,o)=>{const i=t.length,l=k(o.replace(/\n$/,"")),a=r?` data-lang="${k(r)}"`:"";return t.push(`<pre class="og2-md-pre"${a}><code class="og2-md-code">${l}</code></pre>`),`\0CB${i}\0`});return s=k(s),s=xt(s),s=s.replace(/\x00CB(\d+)\x00/g,(n,r)=>t[parseInt(r)]),s}function Ct(e){return/^[\s]*[-*]\s/.test(e)?"ul":/^[\s]*\d+\.\s/.test(e)?"ol":/^#{1,4}\s+/.test(e)?"heading":/^\s*\|/.test(e)?"table":"text"}function vt(e){const t=[];let s=null;for(const n of e){const r=Ct(n);s&&s.type===r?s.lines.push(n):(s&&t.push(s),s={type:r,lines:[n]})}return s&&t.push(s),t}function Ot(e){var t;switch(e.type){case"ul":return`<ul class="og2-md-list">${e.lines.map(n=>`<li>${b(n.replace(/^[\s]*[-*]\s/,""))}</li>`).join("")}</ul>`;case"ol":{const s=e.lines.map(o=>`<li>${b(o.replace(/^[\s]*\d+\.\s/,""))}</li>`).join(""),n=((t=e.lines[0].match(/^[\s]*(\d+)\./))==null?void 0:t[1])??"1";return`<ol class="og2-md-list"${n!=="1"?` start="${n}"`:""}>${s}</ol>`}case"heading":return e.lines.map(s=>{const n=s.match(/^(#{1,4})\s+(.+)$/),r=n[1].length;return`<h${r+2} class="og2-md-heading">${b(n[2])}</h${r+2}>`}).join("");case"table":return Nt(e.lines);case"text":return`<p>${e.lines.map(s=>b(s)).join("<br>")}</p>`}}function R(e){return e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(n=>n.trim())}function _t(e){const t=e.trim(),s=t.startsWith(":"),n=t.endsWith(":");return s&&n?"center":n?"right":"left"}function Rt(e){const t=R(e);return t.length>0&&t.every(s=>/^:?-{1,}:?$/.test(s.trim()))}function Nt(e){if(e.length<2||!Rt(e[1]))return`<p>${e.map(l=>b(l)).join("<br>")}</p>`;const t=R(e[0]),s=R(e[1]).map(_t),n=e.slice(2),r=l=>{const a=s[l];return a&&a!=="left"?` style="text-align:${a}"`:""},o="<thead><tr>"+t.map((l,a)=>`<th${r(a)}>${b(l)}</th>`).join("")+"</tr></thead>";let i="";return n.length>0&&(i=`<tbody>${n.map(a=>{const T=R(a);return"<tr>"+t.map((w,c)=>`<td${r(c)}>${b(T[c]??"")}</td>`).join("")+"</tr>"}).join("")}</tbody>`),`<table class="og2-md-table">${o}${i}</table>`}function xt(e){const t=e.split(/\n{2,}/),s=[];for(const n of t){const r=n.trim();if(!r)continue;if(/^\x00CB\d+\x00$/.test(r)){s.push(r);continue}const o=r.split(`
5
- `),i=vt(o);for(const l of i)s.push(Ot(l))}return s.join("")}const J={none:"none",soft:"0 2px 8px rgba(0,0,0,0.08)",medium:"0 4px 16px rgba(0,0,0,0.12)",strong:"0 8px 32px rgba(0,0,0,0.18)","extra-strong":"0 16px 48px rgba(0,0,0,0.28)"};function At(e,t){if(!e||!t)return;const s=(l,a)=>{a!=null&&a!==""&&e.style.setProperty(l,String(a))},{colors:n,typography:r,dimensions:o,shadow:i}=t;n&&(s("--og2-bg",n.background),s("--og2-border",n.border),s("--og2-text",n.text),s("--og2-messages-bg",n.messagesBackground),s("--og2-agent-bubble",n.agentBubble),s("--og2-agent-bubble-text",n.agentBubbleText),s("--og2-user-bubble",n.userBubble),s("--og2-user-bubble-text",n.userBubbleText),s("--og2-user-bubble-border",n.userBubbleBorder),s("--og2-send-bg",n.sendButtonBackground),s("--og2-send-icon",n.sendButtonIcon),s("--og2-send-inactive-bg",n.sendButtonInactiveBackground)),r&&(s("--og2-font",r.fontFamily),s("--og2-font-weight",r.fontWeight),s("--og2-line-height",r.lineHeight),typeof r.fontSize=="number"&&s("--og2-font-size",`${r.fontSize}px`),typeof r.headerSize=="number"&&s("--og2-header-size",`${r.headerSize}px`),typeof r.letterSpacing=="number"&&s("--og2-letter-spacing",`${r.letterSpacing}px`)),o&&(o.width!==void 0&&s("--og2-width",`${o.width}px`),o.maxHeight!==void 0&&s("--og2-height",`${o.maxHeight}px`),o.borderRadius!==void 0&&s("--og2-radius",`${o.borderRadius}px`),o.padding!==void 0&&s("--og2-padding",`${o.padding}px`)),i&&J[i]&&s("--og2-shadow",J[i])}function kt(e,t){if(!e||!t)return;const s=(n,r)=>{r!=null&&r!==""&&e.style.setProperty(n,String(r))};t.background&&s("--og2-bubble-bg",t.background),t.border&&s("--og2-bubble-border",t.border),t.icon&&s("--og2-bubble-icon",t.icon),t.buttonSize&&s("--og2-bubble-size",`${t.buttonSize}px`),t.iconSize&&s("--og2-bubble-icon-size",`${t.iconSize}px`),t.right!==void 0&&s("--og2-bubble-right",`${t.right}px`),t.bottom!==void 0&&s("--og2-bubble-bottom",`${t.bottom}px`)}exports.OurguideClient=wt;exports.applyAppearance=At;exports.applyBubble=kt;exports.captureDOM=ct;exports.clearEndUserSessionId=st;exports.clearMessages=P;exports.fetchConfig=W;exports.fileToBase64=q;exports.generateId=L;exports.getHandler=tt;exports.getOrCreateEndUserSessionId=_;exports.hasHandler=et;exports.identifyEndUser=K;exports.initialState=Q;exports.loadConversationId=at;exports.loadMessages=ot;exports.navigateTo=lt;exports.parseDataStream=D;exports.registerTools=U;exports.renderMarkdown=$t;exports.resetEndUser=Y;exports.saveConversationId=it;exports.saveMessages=rt;exports.sendMessage=M;exports.widgetReducer=Z;
3
+ `);r=l.pop()??"";for(const a of l)X(a.trim(),t)}r.trim()&&X(r.trim(),t),t.onFinish()}catch(o){const i=o instanceof Error?o.message:"Stream read failed";t.onError(i)}finally{s.releaseLock()}}function X(e,t){const s=e.split(`
4
+ `);for(const n of s){if(!n.startsWith("data: "))continue;const r=n.slice(6);if(r==="[DONE]")return;try{const o=JSON.parse(r);switch(o.type){case"text-delta":o.delta&&t.onTextDelta(o.delta);break;case"tool-input-available":o.toolCallId&&o.toolName&&t.onToolCall(o.toolCallId,o.toolName,o.input??{},o.providerMetadata);break;case"tool-output-available":o.toolCallId&&t.onToolResult(o.toolCallId,o.output);break;case"tool-call":o.toolCallId&&o.toolName&&t.onToolCall(o.toolCallId,o.toolName,o.input??{});break;case"tool-result":o.toolCallId&&t.onToolResult(o.toolCallId,o.output);break;case"error":t.onError(o.errorText??o.reason??"Unknown error");break;case"abort":t.onError(o.reason??"Response aborted");break;default:break}}catch{}}}const ht=10,ft=30,N=500,pt="og2-widget-root",mt=new Set(["SCRIPT","STYLE","NOSCRIPT","SVG","NAV","HEADER","FOOTER"]),St="a[href], button, input, select, textarea";function A(e){if(!(e instanceof HTMLElement))return!1;if(typeof e.checkVisibility=="function")return e.checkVisibility({checkOpacity:!1,checkVisibilityCSS:!0});let t=e;for(;t;){if(t.hidden||t.getAttribute("aria-hidden")==="true")return!1;const s=getComputedStyle(t);if(s.display==="none"||s.visibility==="hidden")return!1;t=t.parentElement}return!0}function x(e){return!!e.closest(`#${pt}`)}function yt(e){var s,n;if(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement){if(e.id){const r=document.querySelector(`label[for="${CSS.escape(e.id)}"]`);if((s=r==null?void 0:r.textContent)!=null&&s.trim())return r.textContent.trim()}return e.getAttribute("aria-label")||e.placeholder||e.getAttribute("name")||""}const t=(n=e.innerText)==null?void 0:n.trim();return t||e.getAttribute("aria-label")||e.getAttribute("title")||""}function V(e,t){return e.length<=t?e:e.slice(0,t-3)+"..."}function et(){var b;const e=window.location.pathname+window.location.search,t=document.title||"",s=document.querySelectorAll("h1, h2, h3"),n=[];for(const c of s){if(n.length>=ht)break;if(x(c)||!A(c))continue;const d=(b=c.innerText)==null?void 0:b.trim();d&&!n.includes(d)&&n.push(d)}const r=document.querySelectorAll(St),o=[],i=new Set;for(const c of r){if(o.length>=ft)break;if(x(c)||!A(c))continue;const d=yt(c);if(!d)continue;const T=`${c.tagName}:${d}`;if(i.has(T))continue;i.add(T);const m={tag:c.tagName.toLowerCase(),text:V(d,80)};if(c instanceof HTMLInputElement&&(m.type=c.type),c instanceof HTMLAnchorElement&&c.href)try{const $=new URL(c.href);m.href=$.pathname+$.search}catch{m.href=c.getAttribute("href")||void 0}o.push(m)}const l=document.querySelector("main")||document.body;let a="";function S(c){var T;if(a.length>=N)return;if(c.nodeType===Node.TEXT_NODE){const m=(T=c.textContent)==null?void 0:T.trim();m&&(a+=(a?" ":"")+m);return}if(c.nodeType!==Node.ELEMENT_NODE)return;const d=c;if(!mt.has(d.tagName)&&!x(d)&&A(d)){for(const m of d.childNodes)if(S(m),a.length>=N)return}}return S(l),a=V(a.replace(/\s+/g," ").trim(),N),{url:e,title:t,headings:n,interactiveElements:o,visibleText:a}}const P={capture_screen:async()=>et()};function st(e){Object.assign(P,e)}function nt(e){return P[e]}function rt(e){return Object.hasOwn(P,e)}const Et="og2-chat-",bt="og2-enduser-session-",H="og2-conv-";function j(e){return`${Et}${e}`}function ot(e){return`${bt}${e}`}function J(){var t,s;const e=(s=(t=globalThis.crypto)==null?void 0:t.randomUUID)==null?void 0:s.call(t);return e||`${Date.now()}-${Math.random().toString(16).slice(2)}`}function O(e){const t=ot(e);try{const s=localStorage.getItem(t);if(s&&s.trim())return s;const n=`sess_${J()}`;return localStorage.setItem(t,n),n}catch{return`sess_${J()}`}}function it(e){try{localStorage.removeItem(ot(e))}catch{}}function at(e,t){try{const s=t.map(({isStreaming:n,...r})=>r);sessionStorage.setItem(j(e),JSON.stringify(s))}catch{}}function ct(e){try{const t=sessionStorage.getItem(j(e));return t?JSON.parse(t):[]}catch{return[]}}function U(e){try{sessionStorage.removeItem(j(e)),sessionStorage.removeItem(`${H}${e}`)}catch{}}function lt(e,t){try{sessionStorage.setItem(`${H}${e}`,t)}catch{}}function ut(e){try{return sessionStorage.getItem(`${H}${e}`)}catch{return null}}function Tt(e,t){if(!t)return e;let s=e;for(const[n,r]of Object.entries(t)){const o=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");s=s.replace(new RegExp(`:${o}(?!\\w)`,"g"),encodeURIComponent(r))}return s}function It(e){var n;const t=e.replace(/\/$/,"")||"/",s=document.querySelectorAll("a[href]");for(const r of s){const o=r,i=((n=o.pathname)==null?void 0:n.replace(/\/$/,""))||"/";if(o.origin===window.location.origin&&i===t)return o.click(),console.log(`[Ourguide] Navigated via anchor click: ${e}`),!0}return!1}function wt(e){var r,o;const t=window,s=t.next;if((r=s==null?void 0:s.router)!=null&&r.push)return s.router.push(e),console.log(`[Ourguide] Navigated via Next.js router: ${e}`),!0;if(t.__NUXT__){const i=t.$nuxt;if((o=i==null?void 0:i.$router)!=null&&o.push)return i.$router.push(e),console.log(`[Ourguide] Navigated via Vue/Nuxt router: ${e}`),!0}return!1}function Ct(e){try{return window.history.pushState({},"",e),window.dispatchEvent(new PopStateEvent("popstate",{state:{}})),console.log(`[Ourguide] Navigated via pushState: ${e}`),!0}catch{return!1}}async function dt(e,t,s){const n=Tt(e,t);return s?(s(n),console.log(`[Ourguide] Navigated via navigate prop: ${n}`),!0):(It(n)||wt(n)||Ct(n)||(console.log(`[Ourguide] Navigated via hard navigation: ${n}`),window.location.href=n),!0)}class $t{constructor(t){this.state=Z,this.conversationId=null,this.callbacks={},this.listeners=new Set,this.abortController=null,this.destroyed=!1,this.productId=t.productId,this.apiUrl=t.apiUrl,this.conversationId=ut(this.productId);const s=ct(this.productId);s.length>0&&this.dispatch({type:"LOAD_MESSAGES",messages:s})}on(t){this.callbacks={...this.callbacks,...t}}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}getSnapshot(){return this.state}getState(){return this.state}getMessages(){return this.state.messages}dispatch(t){var s,n;if(!this.destroyed){this.state=tt(this.state,t),(n=(s=this.callbacks).onStateChange)==null||n.call(s,this.state);for(const r of this.listeners)r(this.state)}}open(){this.dispatch({type:"OPEN"})}close(){this.dispatch({type:"CLOSE"})}registerTools(t){st(t)}async loadConfig(){var s,n;const t=await K(this.apiUrl,this.productId);return(n=(s=this.callbacks).onConfigLoaded)==null||n.call(s,t),t}async identify(t,s){const n=O(this.productId);await Y(this.apiUrl,this.productId,n,t,s)}resetUser(){const t=O(this.productId);Q(this.apiUrl,this.productId,t).catch(()=>{}),it(this.productId),U(this.productId),this.conversationId=null,this.dispatch({type:"FINISH_STREAMING"}),this.dispatch({type:"CLEAR_MESSAGES"})}destroy(){var t;this.destroyed=!0,(t=this.abortController)==null||t.abort(),this.abortController=null,this.listeners.clear(),this.callbacks={}}revive(){this.destroyed=!1}newConversation(){const t=this.state.messages;let s=null;if(t.length>0){const n=t.find(r=>r.role==="user");s={title:n?n.content.slice(0,30):"Conversation",preview:t[t.length-1].content.slice(0,50),messages:[...t]}}return U(this.productId),this.conversationId=null,this.dispatch({type:"CLEAR_MESSAGES"}),s}async sendMessage(t,s,n){var m,$,B,G,F;const r=t.trim(),o=s?[...s]:[];if(!r&&o.length===0||this.state.isStreaming)return;const i=o.length>0?o.map(h=>`[${h.name}]`).join(" "):"",l=[r,i].filter(Boolean).join(" ");this.dispatch({type:"ADD_USER_MESSAGE",id:L(),content:l});let a=[];if(o.length>0)try{a=await Promise.all(o.map(async h=>({name:h.name,type:h.type,data:await W(h)})))}catch{this.dispatch({type:"SET_ERROR",error:"Failed to read attached files"});return}const S=[...this.state.messages.slice(0,-1).map(h=>({role:h.role,content:h.content})),{role:"user",content:r||"Please review the attached file(s)."}];this.dispatch({type:"START_STREAMING",id:L()}),(m=this.abortController)==null||m.abort();const b=new AbortController;this.abortController=b;const c=new Map,d=new Map,T=h=>({onTextDelta:g=>this.dispatch({type:"APPEND_TEXT",text:g}),onToolCall:(g,p,f,y)=>{var E,u;const I={id:g,name:p,args:f,status:"calling",providerMetadata:y};c.set(g,I),this.dispatch({type:"ADD_TOOL_CALL",toolCall:I}),(u=(E=this.callbacks).onToolCall)==null||u.call(E,I),h&&rt(p)&&d.set(g,{name:p,args:f,providerMetadata:y})},onToolResult:(g,p)=>{var y,I;this.dispatch({type:"SET_TOOL_RESULT",toolCallId:g,result:p});const f=c.get(g);if(f&&((I=(y=this.callbacks).onToolResult)==null||I.call(y,f.name,p)),(f==null?void 0:f.name)==="navigate_to_page"){const E=p;E.route&&(E.confidence??0)>=.5&&dt(E.route,E.params,n)}},onError:g=>{var p,f;this.dispatch({type:"SET_ERROR",error:g}),(f=(p=this.callbacks).onError)==null||f.call(p,g)}});try{const h=O(this.productId),{stream:g,conversationId:p}=await M(this.apiUrl,this.productId,S,h,this.conversationId||void 0,a,b.signal);p&&!this.conversationId&&(this.conversationId=p,lt(this.productId,p));let f=!1;if(await D(g,{...T(!0),onError:u=>{var C,v;f=!0,this.dispatch({type:"SET_ERROR",error:u}),(v=(C=this.callbacks).onError)==null||v.call(C,u)},onFinish:()=>{}}),f||d.size===0){f||this.dispatch({type:"FINISH_STREAMING"}),this.persistMessages();return}const y=[];for(const[u,{name:C,args:v,providerMetadata:gt}]of d){let _;try{_=await nt(C)(v)}catch(z){_={status:"error",error:z instanceof Error?z.message:"Handler failed"}}this.dispatch({type:"SET_TOOL_RESULT",toolCallId:u,result:_}),(B=($=this.callbacks).onToolResult)==null||B.call($,C,_),y.push({toolCallId:u,toolName:C,args:v,result:_,providerMetadata:gt})}const I=[...S,{role:"assistant",content:y.map(u=>({type:"tool-call",toolCallId:u.toolCallId,toolName:u.toolName,input:u.args,...u.providerMetadata?{providerOptions:u.providerMetadata}:{}}))},{role:"tool",content:y.map(u=>({type:"tool-result",toolCallId:u.toolCallId,toolName:u.toolName,output:{type:"json",value:u.result}}))}],{stream:E}=await M(this.apiUrl,this.productId,I,void 0,this.conversationId||void 0,void 0,b.signal);await D(E,{...T(!1),onFinish:()=>this.dispatch({type:"FINISH_STREAMING"})})}catch(h){if(this.destroyed||b.signal.aborted)return;this.dispatch({type:"FINISH_STREAMING"});const g=h instanceof Error?h.message:"Something went wrong";this.dispatch({type:"SET_ERROR",error:g}),(F=(G=this.callbacks).onError)==null||F.call(G,g)}this.persistMessages()}persistMessages(){!this.state.isStreaming&&this.state.messages.length>0&&at(this.productId,this.state.messages)}}function vt(e,t){if(e.name==="navigate_to_page"){if(e.status==="calling")return"Finding the right page...";const s=e.result;return s!=null&&s.route?`Navigated to ${s.route}`:"No matching page found"}return e.name==="capture_screen"?e.status==="calling"||t?"Looking at your screen...":"Screen captured":e.name}function k(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function w(e){let t=e;return t=t.replace(/`([^`\n]+)`/g,'<code class="og2-md-inline-code">$1</code>'),t=t.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),t=t.replace(/__(.+?)__/g,"<strong>$1</strong>"),t=t.replace(/\*(.+?)\*/g,"<em>$1</em>"),t=t.replace(new RegExp("(?<!\\w)_(.+?)_(?!\\w)","g"),"<em>$1</em>"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(s,n,r)=>{const o=r.trim();return/^(https?:\/\/|mailto:|\/|#)/i.test(o)?`<a class="og2-md-link" href="${o}" target="_blank" rel="noopener noreferrer">${n}</a>`:n}),t}function _t(e){if(!e)return"";const t=[];let s=e.replace(/```(\w*)\n([\s\S]*?)```/g,(n,r,o)=>{const i=t.length,l=k(o.replace(/\n$/,"")),a=r?` data-lang="${k(r)}"`:"";return t.push(`<pre class="og2-md-pre"${a}><code class="og2-md-code">${l}</code></pre>`),`\0CB${i}\0`});return s=k(s),s=Mt(s),s=s.replace(/\x00CB(\d+)\x00/g,(n,r)=>t[parseInt(r)]),s}function Ot(e){return/^[\s]*[-*]\s/.test(e)?"ul":/^[\s]*\d+\.\s/.test(e)?"ol":/^#{1,4}\s+/.test(e)?"heading":/^\s*\|/.test(e)?"table":"text"}function Rt(e){const t=[];let s=null;for(const n of e){const r=Ot(n);s&&s.type===r?s.lines.push(n):(s&&t.push(s),s={type:r,lines:[n]})}return s&&t.push(s),t}function Nt(e){var t;switch(e.type){case"ul":return`<ul class="og2-md-list">${e.lines.map(n=>`<li>${w(n.replace(/^[\s]*[-*]\s/,""))}</li>`).join("")}</ul>`;case"ol":{const s=e.lines.map(o=>`<li>${w(o.replace(/^[\s]*\d+\.\s/,""))}</li>`).join(""),n=((t=e.lines[0].match(/^[\s]*(\d+)\./))==null?void 0:t[1])??"1";return`<ol class="og2-md-list"${n!=="1"?` start="${n}"`:""}>${s}</ol>`}case"heading":return e.lines.map(s=>{const n=s.match(/^(#{1,4})\s+(.+)$/),r=n[1].length;return`<h${r+2} class="og2-md-heading">${w(n[2])}</h${r+2}>`}).join("");case"table":return kt(e.lines);case"text":return`<p>${e.lines.map(s=>w(s)).join("<br>")}</p>`}}function R(e){return e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(n=>n.trim())}function At(e){const t=e.trim(),s=t.startsWith(":"),n=t.endsWith(":");return s&&n?"center":n?"right":"left"}function xt(e){const t=R(e);return t.length>0&&t.every(s=>/^:?-{1,}:?$/.test(s.trim()))}function kt(e){if(e.length<2||!xt(e[1]))return`<p>${e.map(l=>w(l)).join("<br>")}</p>`;const t=R(e[0]),s=R(e[1]).map(At),n=e.slice(2),r=l=>{const a=s[l];return a&&a!=="left"?` style="text-align:${a}"`:""},o="<thead><tr>"+t.map((l,a)=>`<th${r(a)}>${w(l)}</th>`).join("")+"</tr></thead>";let i="";return n.length>0&&(i=`<tbody>${n.map(a=>{const S=R(a);return"<tr>"+t.map((b,c)=>`<td${r(c)}>${w(S[c]??"")}</td>`).join("")+"</tr>"}).join("")}</tbody>`),`<table class="og2-md-table">${o}${i}</table>`}function Mt(e){const t=e.split(/\n{2,}/),s=[];for(const n of t){const r=n.trim();if(!r)continue;if(/^\x00CB\d+\x00$/.test(r)){s.push(r);continue}const o=r.split(`
5
+ `),i=Rt(o);for(const l of i)s.push(Nt(l))}return s.join("")}const q={none:"none",soft:"0 2px 8px rgba(0,0,0,0.08)",medium:"0 4px 16px rgba(0,0,0,0.12)",strong:"0 8px 32px rgba(0,0,0,0.18)","extra-strong":"0 16px 48px rgba(0,0,0,0.28)"};function Lt(e,t){if(!e||!t)return;const s=(l,a)=>{a!=null&&a!==""&&e.style.setProperty(l,String(a))},{colors:n,typography:r,dimensions:o,shadow:i}=t;n&&(s("--og2-bg",n.background),s("--og2-border",n.border),s("--og2-text",n.text),s("--og2-messages-bg",n.messagesBackground),s("--og2-agent-bubble",n.agentBubble),s("--og2-agent-bubble-text",n.agentBubbleText),s("--og2-user-bubble",n.userBubble),s("--og2-user-bubble-text",n.userBubbleText),s("--og2-user-bubble-border",n.userBubbleBorder),s("--og2-send-bg",n.sendButtonBackground),s("--og2-send-icon",n.sendButtonIcon),s("--og2-send-inactive-bg",n.sendButtonInactiveBackground)),r&&(s("--og2-font",r.fontFamily),s("--og2-font-weight",r.fontWeight),s("--og2-line-height",r.lineHeight),typeof r.fontSize=="number"&&s("--og2-font-size",`${r.fontSize}px`),typeof r.headerSize=="number"&&s("--og2-header-size",`${r.headerSize}px`),typeof r.letterSpacing=="number"&&s("--og2-letter-spacing",`${r.letterSpacing}px`)),o&&(o.width!==void 0&&s("--og2-width",`${o.width}px`),o.maxHeight!==void 0&&s("--og2-height",`${o.maxHeight}px`),o.borderRadius!==void 0&&s("--og2-radius",`${o.borderRadius}px`),o.padding!==void 0&&s("--og2-padding",`${o.padding}px`)),i&&q[i]&&s("--og2-shadow",q[i])}function Dt(e,t){if(!e||!t)return;const s=(n,r)=>{r!=null&&r!==""&&e.style.setProperty(n,String(r))};t.background&&s("--og2-bubble-bg",t.background),t.border&&s("--og2-bubble-border",t.border),t.icon&&s("--og2-bubble-icon",t.icon),t.buttonSize&&s("--og2-bubble-size",`${t.buttonSize}px`),t.iconSize&&s("--og2-bubble-icon-size",`${t.iconSize}px`),t.right!==void 0&&s("--og2-bubble-right",`${t.right}px`),t.bottom!==void 0&&s("--og2-bubble-bottom",`${t.bottom}px`)}exports.OurguideClient=$t;exports.applyAppearance=Lt;exports.applyBubble=Dt;exports.captureDOM=et;exports.clearEndUserSessionId=it;exports.clearMessages=U;exports.fetchConfig=K;exports.fileToBase64=W;exports.formatToolCall=vt;exports.generateId=L;exports.getHandler=nt;exports.getOrCreateEndUserSessionId=O;exports.hasHandler=rt;exports.identifyEndUser=Y;exports.initialState=Z;exports.loadConversationId=ut;exports.loadMessages=ct;exports.navigateTo=dt;exports.parseDataStream=D;exports.registerTools=st;exports.renderMarkdown=_t;exports.resetEndUser=Q;exports.saveConversationId=lt;exports.saveMessages=at;exports.sendMessage=M;exports.widgetReducer=tt;
6
6
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/api.ts","../src/state-machine.ts","../src/stream-parser.ts","../src/client-tool-registry.ts","../src/session.ts","../src/dom-capture.ts","../src/navigator.ts","../src/OurguideClient.ts","../src/markdown.ts","../src/appearance.ts"],"sourcesContent":["export function fileToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result as string;\n resolve(result.split(',')[1]); // strip \"data:...;base64,\"\n };\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsDataURL(file);\n });\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\nexport interface AssistantToolCallMessage {\n role: 'assistant';\n content: Array<{\n type: 'tool-call';\n toolCallId: string;\n toolName: string;\n input: Record<string, unknown>;\n providerOptions?: Record<string, unknown>;\n }>;\n}\n\nexport interface ToolResultMessage {\n role: 'tool';\n content: Array<{\n type: 'tool-result';\n toolCallId: string;\n toolName: string;\n output: { type: 'json'; value: Record<string, unknown> };\n }>;\n}\n\nexport type AnyMessage = ChatMessage | AssistantToolCallMessage | ToolResultMessage;\n\nexport interface SendMessageResult {\n stream: ReadableStream<Uint8Array>;\n conversationId: string | null;\n}\n\nexport interface FileAttachment {\n name: string;\n type: string;\n data: string; // base64\n}\n\nexport interface ProductConfig {\n appearance?: {\n colors?: Record<string, string>;\n typography?: Record<string, string | number>;\n dimensions?: Record<string, number>;\n shadow?: string;\n };\n bubble?: {\n background?: string;\n border?: string;\n icon?: string;\n buttonSize?: number;\n iconSize?: number;\n right?: number;\n bottom?: number;\n };\n identity?: {\n name?: string;\n welcomeMessage?: string;\n };\n suggestions?: Array<{ buttonLabel: string; message: string }>;\n}\n\n/**\n * Fetch product config to know which features are enabled.\n */\nexport async function fetchConfig(\n apiUrl: string,\n productId: string\n): Promise<ProductConfig> {\n const url = `${apiUrl}/api/products/${productId}/config`;\n console.log('[Ourguide] fetchConfig HTTP GET', url);\n try {\n const res = await fetch(url, {\n headers: { 'ngrok-skip-browser-warning': 'true' },\n });\n console.log('[Ourguide] fetchConfig HTTP status:', res.status, res.statusText);\n if (!res.ok) {\n console.warn('[Ourguide] fetchConfig non-OK response, returning {}');\n return {};\n }\n const data = await res.json();\n console.log('[Ourguide] fetchConfig raw JSON:', JSON.stringify(data, null, 2));\n return data;\n } catch (err) {\n console.error('[Ourguide] fetchConfig threw:', err);\n return {};\n }\n}\n\n/**\n * Send a chat message and return the raw ReadableStream for parsing.\n * Uses the /api/chat endpoint which returns a Vercel AI SDK data stream.\n */\nexport async function sendMessage(\n apiUrl: string,\n productId: string,\n messages: AnyMessage[],\n endUserSessionId?: string,\n conversationId?: string,\n attachments?: FileAttachment[]\n): Promise<SendMessageResult> {\n const body: Record<string, unknown> = { productId, messages, endUserSessionId };\n if (conversationId) {\n body.conversationId = conversationId;\n }\n if (attachments && attachments.length > 0) {\n body.attachments = attachments;\n }\n\n const res = await fetch(`${apiUrl}/api/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'ngrok-skip-browser-warning': 'true',\n },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const data = await res.json().catch(() => ({ error: 'Request failed' }));\n throw new Error(data.error || `HTTP ${res.status}`);\n }\n\n if (!res.body) {\n throw new Error('No response stream available');\n }\n\n return {\n stream: res.body,\n conversationId: res.headers.get('X-Conversation-Id'),\n };\n}\n\nexport async function identifyEndUser(\n apiUrl: string,\n productId: string,\n endUserSessionId: string,\n token: string,\n name?: string\n): Promise<{ stored: boolean } & Record<string, unknown>> {\n const res = await fetch(`${apiUrl}/api/widget/identify`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'ngrok-skip-browser-warning': 'true',\n },\n body: JSON.stringify({ productId, endUserSessionId, token, name }),\n });\n\n const data = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error((data as { error?: string }).error || `HTTP ${res.status}`);\n }\n return data as { stored: boolean } & Record<string, unknown>;\n}\n\nexport async function resetEndUser(\n apiUrl: string,\n productId: string,\n endUserSessionId: string\n): Promise<{ deleted: boolean } & Record<string, unknown>> {\n const res = await fetch(`${apiUrl}/api/widget/reset-user`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'ngrok-skip-browser-warning': 'true',\n },\n body: JSON.stringify({ productId, endUserSessionId }),\n });\n\n const data = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error((data as { error?: string }).error || `HTTP ${res.status}`);\n }\n return data as { deleted: boolean } & Record<string, unknown>;\n}\n","export interface ToolCallInfo {\n id: string;\n name: string;\n args: Record<string, unknown>;\n result?: unknown;\n status: 'calling' | 'done' | 'error';\n /** Provider-specific metadata from the LLM response (e.g. Gemini thought signatures). */\n providerMetadata?: Record<string, unknown>;\n}\n\nexport interface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n toolCalls?: ToolCallInfo[];\n isStreaming?: boolean;\n}\n\nexport interface WidgetState {\n isOpen: boolean;\n messages: Message[];\n isStreaming: boolean;\n error: string | null;\n}\n\nexport type WidgetAction =\n | { type: 'OPEN' }\n | { type: 'CLOSE' }\n | { type: 'LOAD_MESSAGES'; messages: Message[] }\n | { type: 'ADD_USER_MESSAGE'; id: string; content: string }\n | { type: 'START_STREAMING'; id: string }\n | { type: 'APPEND_TEXT'; text: string }\n | { type: 'ADD_TOOL_CALL'; toolCall: ToolCallInfo }\n | { type: 'SET_TOOL_RESULT'; toolCallId: string; result: unknown }\n | { type: 'FINISH_STREAMING' }\n | { type: 'SET_ERROR'; error: string }\n | { type: 'CLEAR_MESSAGES' };\n\nexport const initialState: WidgetState = {\n isOpen: false,\n messages: [],\n isStreaming: false,\n error: null,\n};\n\nfunction generateId(): string {\n return Date.now().toString(36) + Math.random().toString(36).slice(2, 7);\n}\n\nexport { generateId };\n\nexport function widgetReducer(state: WidgetState, action: WidgetAction): WidgetState {\n switch (action.type) {\n case 'OPEN':\n return { ...state, isOpen: true, error: null };\n\n case 'CLOSE':\n return { ...state, isOpen: false };\n\n case 'LOAD_MESSAGES':\n return { ...state, messages: action.messages };\n\n case 'ADD_USER_MESSAGE':\n return {\n ...state,\n error: null,\n messages: [\n ...state.messages,\n { id: action.id, role: 'user', content: action.content },\n ],\n };\n\n case 'START_STREAMING':\n return {\n ...state,\n isStreaming: true,\n error: null,\n messages: [\n ...state.messages,\n { id: action.id, role: 'assistant', content: '', isStreaming: true },\n ],\n };\n\n case 'APPEND_TEXT': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n msgs[msgs.length - 1] = { ...last, content: last.content + action.text };\n }\n return { ...state, messages: msgs };\n }\n\n case 'ADD_TOOL_CALL': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant') {\n const toolCalls = [...(last.toolCalls ?? []), action.toolCall];\n msgs[msgs.length - 1] = { ...last, toolCalls };\n }\n return { ...state, messages: msgs };\n }\n\n case 'SET_TOOL_RESULT': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant' && last.toolCalls) {\n const toolCalls = last.toolCalls.map((tc) =>\n tc.id === action.toolCallId\n ? { ...tc, result: action.result, status: 'done' as const }\n : tc\n );\n msgs[msgs.length - 1] = { ...last, toolCalls };\n }\n return { ...state, messages: msgs };\n }\n\n case 'FINISH_STREAMING': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n // If only tool calls arrived with no text, remove the empty assistant message\n if (!last.content && last.toolCalls?.length) {\n msgs.pop();\n } else {\n msgs[msgs.length - 1] = { ...last, isStreaming: false };\n }\n }\n return { ...state, isStreaming: false, messages: msgs };\n }\n\n case 'SET_ERROR': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n msgs[msgs.length - 1] = { ...last, isStreaming: false };\n }\n return { ...state, isStreaming: false, error: action.error, messages: msgs };\n }\n\n case 'CLEAR_MESSAGES':\n return { ...state, messages: [], error: null, isStreaming: false };\n\n default:\n return state;\n }\n}\n","/**\n * Lightweight parser for the Vercel AI SDK UI Message Stream protocol (SSE format).\n *\n * Protocol format (AI SDK v6): Server-Sent Events\n * data: {\"type\":\"text-delta\",\"delta\":\"...\",\"id\":\"...\"}\\n\\n\n * data: {\"type\":\"tool-input-start\",\"toolCallId\":\"...\",\"toolName\":\"...\"}\\n\\n\n * data: {\"type\":\"tool-input-delta\",\"toolCallId\":\"...\",\"inputTextDelta\":\"...\"}\\n\\n\n * data: {\"type\":\"tool-input-available\",\"toolCallId\":\"...\",\"toolName\":\"...\",\"input\":{...}}\\n\\n\n * data: {\"type\":\"tool-output-available\",\"toolCallId\":\"...\",\"output\":{...}}\\n\\n\n * data: {\"type\":\"finish\"}\\n\\n\n * data: [DONE]\\n\\n\n */\n\nexport interface StreamCallbacks {\n onTextDelta: (text: string) => void;\n onToolCall: (id: string, name: string, args: Record<string, unknown>, providerMetadata?: Record<string, unknown>) => void;\n onToolResult: (id: string, result: unknown) => void;\n onFinish: () => void;\n onError: (error: string) => void;\n}\n\nexport async function parseDataStream(\n body: ReadableStream<Uint8Array>,\n callbacks: StreamCallbacks\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n buffer += done\n ? decoder.decode()\n : decoder.decode(value, { stream: true });\n\n if (done) break;\n\n // SSE events are separated by double newlines\n const parts = buffer.split('\\n\\n');\n // Keep the last incomplete part in the buffer\n buffer = parts.pop() ?? '';\n\n for (const part of parts) {\n processSSEEvent(part.trim(), callbacks);\n }\n }\n\n // Process any remaining buffer\n if (buffer.trim()) {\n processSSEEvent(buffer.trim(), callbacks);\n }\n\n callbacks.onFinish();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Stream read failed';\n callbacks.onError(message);\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction processSSEEvent(event: string, callbacks: StreamCallbacks): void {\n // SSE lines start with \"data: \"\n const lines = event.split('\\n');\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue;\n\n const payload = line.slice(6); // Remove \"data: \" prefix\n\n // End of stream marker\n if (payload === '[DONE]') return;\n\n try {\n const chunk = JSON.parse(payload) as {\n type: string;\n delta?: string;\n toolCallId?: string;\n toolName?: string;\n input?: Record<string, unknown>;\n inputTextDelta?: string;\n output?: unknown;\n finishReason?: string;\n reason?: string;\n errorText?: string;\n providerMetadata?: Record<string, unknown>;\n };\n\n switch (chunk.type) {\n case 'text-delta':\n if (chunk.delta) {\n callbacks.onTextDelta(chunk.delta);\n }\n break;\n\n // AI SDK v6: tool-input-available fires when tool input is fully parsed\n case 'tool-input-available':\n if (chunk.toolCallId && chunk.toolName) {\n callbacks.onToolCall(\n chunk.toolCallId,\n chunk.toolName,\n (chunk.input as Record<string, unknown>) ?? {},\n chunk.providerMetadata\n );\n }\n break;\n\n // AI SDK v6: tool-output-available fires when tool execution completes\n case 'tool-output-available':\n if (chunk.toolCallId) {\n callbacks.onToolResult(chunk.toolCallId, chunk.output);\n }\n break;\n\n // Legacy event names (AI SDK v5 compat)\n case 'tool-call':\n if (chunk.toolCallId && chunk.toolName) {\n callbacks.onToolCall(\n chunk.toolCallId,\n chunk.toolName,\n (chunk.input as Record<string, unknown>) ?? {}\n );\n }\n break;\n\n case 'tool-result':\n if (chunk.toolCallId) {\n callbacks.onToolResult(chunk.toolCallId, chunk.output);\n }\n break;\n\n case 'error':\n callbacks.onError(chunk.errorText ?? chunk.reason ?? 'Unknown error');\n break;\n\n case 'abort':\n callbacks.onError(chunk.reason ?? 'Response aborted');\n break;\n\n // Ignore: start, finish, text-start, text-end, start-step, finish-step,\n // tool-input-start, tool-input-delta\n default:\n break;\n }\n } catch {\n // Skip malformed JSON silently\n }\n }\n}\n","export type ToolHandler = (args: Record<string, unknown>) => Promise<Record<string, unknown>>;\nexport type ToolHandlerMap = Record<string, ToolHandler>;\n\nconst handlers: ToolHandlerMap = {};\n\nexport function registerTools(newHandlers: ToolHandlerMap): void {\n Object.assign(handlers, newHandlers);\n}\n\nexport function getHandler(name: string): ToolHandler | undefined {\n return handlers[name];\n}\n\nexport function hasHandler(name: string): boolean {\n return Object.hasOwn(handlers, name);\n}\n","import type { Message } from './state-machine';\n\nconst KEY_PREFIX = 'og2-chat-';\nconst END_USER_SESSION_PREFIX = 'og2-enduser-session-';\nconst CONVERSATION_ID_PREFIX = 'og2-conv-';\n\nfunction getKey(productId: string): string {\n return `${KEY_PREFIX}${productId}`;\n}\n\nfunction getEndUserSessionKey(productId: string): string {\n return `${END_USER_SESSION_PREFIX}${productId}`;\n}\n\nfunction randomId(): string {\n const uuid = globalThis.crypto?.randomUUID?.();\n if (uuid) return uuid;\n // Fallback for older environments\n return `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nexport function getOrCreateEndUserSessionId(productId: string): string {\n const key = getEndUserSessionKey(productId);\n try {\n const existing = localStorage.getItem(key);\n if (existing && existing.trim()) return existing;\n const created = `sess_${randomId()}`;\n localStorage.setItem(key, created);\n return created;\n } catch {\n return `sess_${randomId()}`;\n }\n}\n\nexport function clearEndUserSessionId(productId: string): void {\n try {\n localStorage.removeItem(getEndUserSessionKey(productId));\n } catch {\n // fail silently\n }\n}\n\nexport function saveMessages(productId: string, messages: Message[]): void {\n try {\n // Strip streaming flags before persisting\n const cleaned = messages.map(({ isStreaming, ...rest }) => rest);\n sessionStorage.setItem(getKey(productId), JSON.stringify(cleaned));\n } catch {\n // sessionStorage might be unavailable or full — fail silently\n }\n}\n\nexport function loadMessages(productId: string): Message[] {\n try {\n const raw = sessionStorage.getItem(getKey(productId));\n if (!raw) return [];\n return JSON.parse(raw) as Message[];\n } catch {\n return [];\n }\n}\n\nexport function clearMessages(productId: string): void {\n try {\n sessionStorage.removeItem(getKey(productId));\n sessionStorage.removeItem(`${CONVERSATION_ID_PREFIX}${productId}`);\n } catch {\n // fail silently\n }\n}\n\nexport function saveConversationId(productId: string, conversationId: string): void {\n try {\n sessionStorage.setItem(`${CONVERSATION_ID_PREFIX}${productId}`, conversationId);\n } catch {\n // fail silently\n }\n}\n\nexport function loadConversationId(productId: string): string | null {\n try {\n return sessionStorage.getItem(`${CONVERSATION_ID_PREFIX}${productId}`);\n } catch {\n return null;\n }\n}\n\nexport function clearConversationId(productId: string): void {\n try {\n sessionStorage.removeItem(`${CONVERSATION_ID_PREFIX}${productId}`);\n } catch {\n // fail silently\n }\n}\n","/**\n * Lightweight DOM snapshot for screen context.\n * Captures just enough for an LLM to understand the current page.\n *\n * Current caps (roughly ~500-1000 tokens per snapshot):\n * - Headings (h1-h3): max 10\n * - Interactive elements (buttons, links, inputs): max 30, labels truncated to 80 chars\n * - Visible text (from <main> or <body>): max 500 chars\n * - Skips: hidden elements, input values (PII), widget's own DOM, scripts/styles/nav/header/footer\n */\n\nexport interface InteractiveElement {\n tag: string;\n text: string;\n type?: string;\n href?: string;\n}\n\nexport interface ScreenContext {\n url: string;\n title: string;\n headings: string[];\n interactiveElements: InteractiveElement[];\n visibleText: string;\n}\n\nconst MAX_HEADINGS = 10;\nconst MAX_INTERACTIVE = 30;\nconst MAX_VISIBLE_TEXT = 500;\n\nconst WIDGET_ROOT_ID = 'og2-widget-root';\n\n/** Tags to skip when extracting visible text */\nconst SKIP_TEXT_TAGS = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'SVG', 'NAV', 'HEADER', 'FOOTER']);\n\n/** Interactive element selectors */\nconst INTERACTIVE_SELECTOR = 'a[href], button, input, select, textarea';\n\nfunction isVisible(el: Element): boolean {\n if (!(el instanceof HTMLElement)) return false;\n // checkVisibility walks the full ancestor chain (Chrome 105+, Firefox 124+)\n if (typeof el.checkVisibility === 'function') {\n return el.checkVisibility({ checkOpacity: false, checkVisibilityCSS: true });\n }\n // Fallback: walk ancestors manually to catch hidden parents\n let node: HTMLElement | null = el;\n while (node) {\n if (node.hidden || node.getAttribute('aria-hidden') === 'true') return false;\n const style = getComputedStyle(node);\n if (style.display === 'none' || style.visibility === 'hidden') return false;\n node = node.parentElement;\n }\n return true;\n}\n\nfunction isInsideWidget(el: Element): boolean {\n return !!el.closest(`#${WIDGET_ROOT_ID}`);\n}\n\nfunction getLabel(el: Element): string {\n if (el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {\n // Try associated label\n if (el.id) {\n const label = document.querySelector(`label[for=\"${CSS.escape(el.id)}\"]`);\n if (label?.textContent?.trim()) return label.textContent.trim();\n }\n // Fallback to aria-label, placeholder, or name\n return (\n el.getAttribute('aria-label') ||\n (el as HTMLInputElement).placeholder ||\n el.getAttribute('name') ||\n ''\n );\n }\n\n // For buttons and links: innerText, aria-label, or title\n const text = (el as HTMLElement).innerText?.trim();\n if (text) return text;\n return el.getAttribute('aria-label') || el.getAttribute('title') || '';\n}\n\nfunction truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 3) + '...';\n}\n\nexport function captureDOM(): ScreenContext {\n // 1. Page metadata — pathname only, avoid leaking host/environment info\n const url = window.location.pathname + window.location.search;\n const title = document.title || '';\n\n // 2. Headings (h1-h3)\n const headingEls = document.querySelectorAll('h1, h2, h3');\n const headings: string[] = [];\n for (const h of headingEls) {\n if (headings.length >= MAX_HEADINGS) break;\n if (isInsideWidget(h) || !isVisible(h)) continue;\n const text = (h as HTMLElement).innerText?.trim();\n if (text && !headings.includes(text)) {\n headings.push(text);\n }\n }\n\n // 3. Interactive elements\n const interactiveEls = document.querySelectorAll(INTERACTIVE_SELECTOR);\n const interactiveElements: InteractiveElement[] = [];\n const seenLabels = new Set<string>();\n\n for (const el of interactiveEls) {\n if (interactiveElements.length >= MAX_INTERACTIVE) break;\n if (isInsideWidget(el) || !isVisible(el)) continue;\n\n const label = getLabel(el);\n if (!label) continue;\n\n // Deduplicate by label+tag\n const key = `${el.tagName}:${label}`;\n if (seenLabels.has(key)) continue;\n seenLabels.add(key);\n\n const item: InteractiveElement = {\n tag: el.tagName.toLowerCase(),\n text: truncate(label, 80),\n };\n\n if (el instanceof HTMLInputElement) {\n item.type = el.type;\n }\n if (el instanceof HTMLAnchorElement && el.href) {\n // Store relative path to avoid leaking full URLs\n try {\n const parsed = new URL(el.href);\n item.href = parsed.pathname + parsed.search;\n } catch {\n item.href = el.getAttribute('href') || undefined;\n }\n }\n\n interactiveElements.push(item);\n }\n\n // 4. Visible text from main content\n const mainEl = document.querySelector('main') || document.body;\n let visibleText = '';\n\n function walkText(node: Node) {\n if (visibleText.length >= MAX_VISIBLE_TEXT) return;\n\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent?.trim();\n if (text) {\n visibleText += (visibleText ? ' ' : '') + text;\n }\n return;\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n const el = node as Element;\n\n if (SKIP_TEXT_TAGS.has(el.tagName)) return;\n if (isInsideWidget(el)) return;\n if (!isVisible(el)) return;\n\n for (const child of el.childNodes) {\n walkText(child);\n if (visibleText.length >= MAX_VISIBLE_TEXT) return;\n }\n }\n\n walkText(mainEl);\n visibleText = truncate(visibleText.replace(/\\s+/g, ' ').trim(), MAX_VISIBLE_TEXT);\n\n return { url, title, headings, interactiveElements, visibleText };\n}\n","/**\n * Substitute dynamic segments in a route pattern with actual values.\n * e.g., \"/users/:userId/profile\" + { userId: \"42\" } => \"/users/42/profile\"\n */\nfunction substituteParams(route: string, params?: Record<string, string>): string {\n if (!params) return route;\n let result = route;\n for (const [key, value] of Object.entries(params)) {\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n result = result.replace(new RegExp(`:${escapedKey}(?!\\\\w)`, 'g'), encodeURIComponent(value));\n }\n return result;\n}\n\nexport type NavigateFn = (path: string) => void;\n\nfunction tryAnchorClick(path: string): boolean {\n const normalized = path.replace(/\\/$/, '') || '/';\n const anchors = document.querySelectorAll('a[href]');\n for (const el of anchors) {\n const anchor = el as HTMLAnchorElement;\n const href = anchor.pathname?.replace(/\\/$/, '') || '/';\n if (anchor.origin === window.location.origin && href === normalized) {\n anchor.click();\n console.log(`[Ourguide] Navigated via anchor click: ${path}`);\n return true;\n }\n }\n return false;\n}\n\nfunction tryFrameworkRouter(path: string): boolean {\n const win = window as unknown as Record<string, unknown>;\n\n // Next.js\n const next = win.next as { router?: { push?: (path: string) => void } } | undefined;\n if (next?.router?.push) {\n next.router.push(path);\n console.log(`[Ourguide] Navigated via Next.js router: ${path}`);\n return true;\n }\n\n // Nuxt / Vue\n const nuxt = win.__NUXT__ as Record<string, unknown> | undefined;\n if (nuxt) {\n const nuxtApp = win.$nuxt as { $router?: { push?: (path: string) => void } } | undefined;\n if (nuxtApp?.$router?.push) {\n nuxtApp.$router.push(path);\n console.log(`[Ourguide] Navigated via Vue/Nuxt router: ${path}`);\n return true;\n }\n }\n\n return false;\n}\n\nfunction tryPushState(path: string): boolean {\n try {\n window.history.pushState({}, '', path);\n window.dispatchEvent(new PopStateEvent('popstate', { state: {} }));\n console.log(`[Ourguide] Navigated via pushState: ${path}`);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Navigate to a route using a four-tier cascade:\n * 1. Consumer-provided navigate fn (e.g. Next.js router.push passed as prop)\n * 2. Click matching anchor in the DOM\n * 3. Auto-detect framework router (Next.js / Nuxt / Vue)\n * 4. pushState + popstate event\n * 5. Hard navigation fallback\n */\nexport async function navigateTo(\n route: string,\n params?: Record<string, string>,\n navigateFn?: NavigateFn,\n): Promise<boolean> {\n const path = substituteParams(route, params);\n\n // Tier 1: explicit navigate prop\n if (navigateFn) {\n navigateFn(path);\n console.log(`[Ourguide] Navigated via navigate prop: ${path}`);\n return true;\n }\n\n // Tier 2: anchor click\n if (tryAnchorClick(path)) return true;\n\n // Tier 3: framework router auto-detection\n if (tryFrameworkRouter(path)) return true;\n\n // Tier 4: pushState\n if (tryPushState(path)) return true;\n\n // Tier 5: hard navigation (always works)\n console.log(`[Ourguide] Navigated via hard navigation: ${path}`);\n window.location.href = path;\n return true;\n}\n","import { sendMessage, fetchConfig, identifyEndUser, resetEndUser, fileToBase64 } from './api';\nimport type { AnyMessage, ChatMessage, FileAttachment, ProductConfig, SendMessageResult } from './api';\nimport { widgetReducer, initialState, generateId } from './state-machine';\nimport type { Message, ToolCallInfo, WidgetState, WidgetAction } from './state-machine';\nimport { parseDataStream } from './stream-parser';\nimport type { StreamCallbacks } from './stream-parser';\nimport { registerTools, hasHandler, getHandler } from './client-tool-registry';\nimport type { ToolHandler, ToolHandlerMap } from './client-tool-registry';\nimport { saveMessages, loadMessages, clearMessages, getOrCreateEndUserSessionId, clearEndUserSessionId, saveConversationId, loadConversationId } from './session';\nimport { captureDOM } from './dom-capture';\nimport type { ScreenContext } from './dom-capture';\nimport { renderMarkdown } from './markdown';\nimport { navigateTo } from './navigator';\nimport type { NavigateFn } from './navigator';\nimport { applyAppearance, applyBubble } from './appearance';\n\nexport interface OurguideClientOptions {\n productId: string;\n apiUrl: string;\n}\n\nexport interface OurguideClientCallbacks {\n onStateChange?: (state: WidgetState) => void;\n onMessage?: (message: Message) => void;\n onToolCall?: (toolCall: ToolCallInfo) => void;\n onToolResult?: (toolName: string, result: unknown) => void;\n onError?: (error: string) => void;\n onConfigLoaded?: (config: ProductConfig) => void;\n}\n\nexport class OurguideClient {\n readonly productId: string;\n readonly apiUrl: string;\n\n private state: WidgetState = initialState;\n private conversationId: string | null = null;\n private callbacks: OurguideClientCallbacks = {};\n\n constructor(options: OurguideClientOptions) {\n this.productId = options.productId;\n this.apiUrl = options.apiUrl;\n\n this.conversationId = loadConversationId(this.productId);\n const saved = loadMessages(this.productId);\n if (saved.length > 0) {\n this.dispatch({ type: 'LOAD_MESSAGES', messages: saved });\n }\n\n registerTools({\n capture_screen: async () => {\n const ctx = captureDOM();\n return ctx as unknown as Record<string, unknown>;\n },\n });\n }\n\n on(callbacks: OurguideClientCallbacks): void {\n this.callbacks = { ...this.callbacks, ...callbacks };\n }\n\n getState(): WidgetState {\n return this.state;\n }\n\n getMessages(): Message[] {\n return this.state.messages;\n }\n\n dispatch(action: WidgetAction): void {\n this.state = widgetReducer(this.state, action);\n this.callbacks.onStateChange?.(this.state);\n }\n\n open(): void {\n this.dispatch({ type: 'OPEN' });\n }\n\n close(): void {\n this.dispatch({ type: 'CLOSE' });\n }\n\n registerTools(tools: ToolHandlerMap): void {\n registerTools(tools);\n }\n\n async loadConfig(): Promise<ProductConfig> {\n const config = await fetchConfig(this.apiUrl, this.productId);\n this.callbacks.onConfigLoaded?.(config);\n return config;\n }\n\n async identify(token: string, name?: string): Promise<void> {\n const sessionId = getOrCreateEndUserSessionId(this.productId);\n await identifyEndUser(this.apiUrl, this.productId, sessionId, token, name);\n }\n\n resetUser(): void {\n const sessionId = getOrCreateEndUserSessionId(this.productId);\n resetEndUser(this.apiUrl, this.productId, sessionId).catch(() => {});\n clearEndUserSessionId(this.productId);\n clearMessages(this.productId);\n this.conversationId = null;\n this.dispatch({ type: 'FINISH_STREAMING' });\n this.dispatch({ type: 'CLEAR_MESSAGES' });\n }\n\n newConversation(): { title: string; preview: string; messages: Message[] } | null {\n const msgs = this.state.messages;\n let saved: { title: string; preview: string; messages: Message[] } | null = null;\n if (msgs.length > 0) {\n const first = msgs.find((m) => m.role === 'user');\n saved = {\n title: first ? first.content.slice(0, 30) : 'Conversation',\n preview: msgs[msgs.length - 1].content.slice(0, 50),\n messages: [...msgs],\n };\n }\n clearMessages(this.productId);\n this.conversationId = null;\n this.dispatch({ type: 'CLEAR_MESSAGES' });\n return saved;\n }\n\n async sendMessage(\n text: string,\n files?: File[],\n navigateFn?: NavigateFn,\n ): Promise<void> {\n const trimmed = text.trim();\n const filesToSend = files ? [...files] : [];\n if ((!trimmed && filesToSend.length === 0) || this.state.isStreaming) return;\n\n const fileLabel = filesToSend.length > 0 ? filesToSend.map((f) => `[${f.name}]`).join(' ') : '';\n const displayContent = [trimmed, fileLabel].filter(Boolean).join(' ');\n this.dispatch({ type: 'ADD_USER_MESSAGE', id: generateId(), content: displayContent });\n\n let fileAttachments: FileAttachment[] = [];\n if (filesToSend.length > 0) {\n try {\n fileAttachments = await Promise.all(filesToSend.map(async (f) => ({ name: f.name, type: f.type, data: await fileToBase64(f) })));\n } catch {\n this.dispatch({ type: 'SET_ERROR', error: 'Failed to read attached files' });\n return;\n }\n }\n\n const apiMessages: ChatMessage[] = [\n ...this.state.messages.map((m) => ({ role: m.role, content: m.content })),\n { role: 'user' as const, content: trimmed || 'Please review the attached file(s).' },\n ];\n\n this.dispatch({ type: 'START_STREAMING', id: generateId() });\n const pendingToolCalls = new Map<string, ToolCallInfo>();\n const pendingClientCalls = new Map<string, { name: string; args: Record<string, unknown>; providerMetadata?: Record<string, unknown> }>();\n\n const makeCallbacks = (allowClientTools: boolean) => ({\n onTextDelta: (delta: string) => this.dispatch({ type: 'APPEND_TEXT', text: delta }),\n onToolCall: (id: string, name: string, args: Record<string, unknown>, providerMetadata?: Record<string, unknown>) => {\n const tc: ToolCallInfo = { id, name, args, status: 'calling', providerMetadata };\n pendingToolCalls.set(id, tc);\n this.dispatch({ type: 'ADD_TOOL_CALL', toolCall: tc });\n this.callbacks.onToolCall?.(tc);\n if (allowClientTools && hasHandler(name)) pendingClientCalls.set(id, { name, args, providerMetadata });\n },\n onToolResult: (id: string, result: unknown) => {\n this.dispatch({ type: 'SET_TOOL_RESULT', toolCallId: id, result });\n const tc = pendingToolCalls.get(id);\n if (tc) this.callbacks.onToolResult?.(tc.name, result);\n if (tc?.name === 'navigate_to_page') {\n const nav = result as { route?: string | null; confidence?: number; params?: Record<string, string> };\n if (nav.route && (nav.confidence ?? 0) >= 0.5) navigateTo(nav.route, nav.params, navigateFn);\n }\n },\n onError: (error: string) => {\n this.dispatch({ type: 'SET_ERROR', error });\n this.callbacks.onError?.(error);\n },\n });\n\n try {\n const endUserSessionId = getOrCreateEndUserSessionId(this.productId);\n const { stream, conversationId: retConvId } = await sendMessage(this.apiUrl, this.productId, apiMessages, endUserSessionId, this.conversationId || undefined, fileAttachments);\n if (retConvId && !this.conversationId) {\n this.conversationId = retConvId;\n saveConversationId(this.productId, retConvId);\n }\n\n let hadError = false;\n await parseDataStream(stream, { ...makeCallbacks(true), onError: (e) => { hadError = true; this.dispatch({ type: 'SET_ERROR', error: e }); this.callbacks.onError?.(e); }, onFinish: () => {} });\n if (hadError || pendingClientCalls.size === 0) { if (!hadError) this.dispatch({ type: 'FINISH_STREAMING' }); this.persistMessages(); return; }\n\n const toolResults: Array<{ toolCallId: string; toolName: string; args: Record<string, unknown>; result: Record<string, unknown>; providerMetadata?: Record<string, unknown> }> = [];\n for (const [id, { name, args, providerMetadata }] of pendingClientCalls) {\n let result: Record<string, unknown>;\n try { result = await getHandler(name)!(args); } catch (err) { result = { status: 'error', error: err instanceof Error ? err.message : 'Handler failed' }; }\n this.dispatch({ type: 'SET_TOOL_RESULT', toolCallId: id, result });\n this.callbacks.onToolResult?.(name, result);\n toolResults.push({ toolCallId: id, toolName: name, args, result, providerMetadata });\n }\n\n const contMessages: AnyMessage[] = [\n ...apiMessages,\n { role: 'assistant', content: toolResults.map((tr) => ({ type: 'tool-call' as const, toolCallId: tr.toolCallId, toolName: tr.toolName, input: tr.args, ...(tr.providerMetadata ? { providerOptions: tr.providerMetadata } : {}) })) },\n { role: 'tool', content: toolResults.map((tr) => ({ type: 'tool-result' as const, toolCallId: tr.toolCallId, toolName: tr.toolName, output: { type: 'json' as const, value: tr.result } })) },\n ];\n const { stream: contStream } = await sendMessage(this.apiUrl, this.productId, contMessages, undefined, this.conversationId || undefined);\n await parseDataStream(contStream, { ...makeCallbacks(false), onFinish: () => this.dispatch({ type: 'FINISH_STREAMING' }) });\n } catch (err) {\n this.dispatch({ type: 'FINISH_STREAMING' });\n const msg = err instanceof Error ? err.message : 'Something went wrong';\n this.dispatch({ type: 'SET_ERROR', error: msg });\n this.callbacks.onError?.(msg);\n }\n\n this.persistMessages();\n }\n\n private persistMessages(): void {\n if (!this.state.isStreaming && this.state.messages.length > 0) {\n saveMessages(this.productId, this.state.messages);\n }\n }\n}\n","/**\n * Lightweight markdown-to-HTML renderer for the chat widget.\n * Handles the most common patterns produced by LLMs without external dependencies.\n * ~2-3KB minified.\n */\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/** Apply inline formatting (code, bold, italic, links) to already-escaped text. */\nfunction applyInline(text: string): string {\n let result = text;\n\n // Inline code (must come before bold/italic to avoid conflicts)\n result = result.replace(/`([^`\\n]+)`/g, '<code class=\"og2-md-inline-code\">$1</code>');\n\n // Bold (**text** or __text__)\n result = result.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n result = result.replace(/__(.+?)__/g, '<strong>$1</strong>');\n\n // Italic (*text* or _text_) — avoid matching inside words for underscores\n result = result.replace(/\\*(.+?)\\*/g, '<em>$1</em>');\n result = result.replace(/(?<!\\w)_(.+?)_(?!\\w)/g, '<em>$1</em>');\n\n // Links [text](url) — only allow safe URL schemes\n result = result.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n (_, linkText, url) => {\n const trimmed = url.trim();\n if (/^(https?:\\/\\/|mailto:|\\/|#)/i.test(trimmed)) {\n return `<a class=\"og2-md-link\" href=\"${trimmed}\" target=\"_blank\" rel=\"noopener noreferrer\">${linkText}</a>`;\n }\n return linkText;\n },\n );\n\n return result;\n}\n\nexport function renderMarkdown(text: string): string {\n if (!text) return '';\n\n // 1. Extract fenced code blocks to protect from all processing\n const codeBlocks: string[] = [];\n let processed = text.replace(/```(\\w*)\\n([\\s\\S]*?)```/g, (_, lang, code) => {\n const idx = codeBlocks.length;\n const escaped = escapeHtml(code.replace(/\\n$/, ''));\n const langAttr = lang ? ` data-lang=\"${escapeHtml(lang)}\"` : '';\n codeBlocks.push(\n `<pre class=\"og2-md-pre\"${langAttr}><code class=\"og2-md-code\">${escaped}</code></pre>`,\n );\n return `\\x00CB${idx}\\x00`;\n });\n\n // 2. Escape HTML in remaining text\n processed = escapeHtml(processed);\n\n // 3. Process blocks (detects structure before inline formatting touches markers)\n processed = processBlocks(processed);\n\n // 4. Restore code blocks\n processed = processed.replace(/\\x00CB(\\d+)\\x00/g, (_, idx) => codeBlocks[parseInt(idx)]);\n\n return processed;\n}\n\ntype LineType = 'ul' | 'ol' | 'heading' | 'table' | 'text';\ntype Segment = { type: LineType; lines: string[] };\n\n/** Classify a single line by its markdown structure. */\nfunction classifyLine(line: string): LineType {\n if (/^[\\s]*[-*]\\s/.test(line)) return 'ul';\n if (/^[\\s]*\\d+\\.\\s/.test(line)) return 'ol';\n if (/^#{1,4}\\s+/.test(line)) return 'heading';\n if (/^\\s*\\|/.test(line)) return 'table';\n return 'text';\n}\n\n/** Group consecutive lines of the same type into segments. */\nfunction segmentLines(lines: string[]): Segment[] {\n const segments: Segment[] = [];\n let current: Segment | null = null;\n\n for (const line of lines) {\n const type = classifyLine(line);\n if (current && current.type === type) {\n current.lines.push(line);\n } else {\n if (current) segments.push(current);\n current = { type, lines: [line] };\n }\n }\n if (current) segments.push(current);\n return segments;\n}\n\n/** Render a single segment into HTML. */\nfunction renderSegment(segment: Segment): string {\n switch (segment.type) {\n case 'ul': {\n const items = segment.lines\n .map((l) => `<li>${applyInline(l.replace(/^[\\s]*[-*]\\s/, ''))}</li>`)\n .join('');\n return `<ul class=\"og2-md-list\">${items}</ul>`;\n }\n case 'ol': {\n const items = segment.lines\n .map((l) => `<li>${applyInline(l.replace(/^[\\s]*\\d+\\.\\s/, ''))}</li>`)\n .join('');\n const startNum = segment.lines[0].match(/^[\\s]*(\\d+)\\./)?.[1] ?? '1';\n const startAttr = startNum !== '1' ? ` start=\"${startNum}\"` : '';\n return `<ol class=\"og2-md-list\"${startAttr}>${items}</ol>`;\n }\n case 'heading':\n return segment.lines\n .map((line) => {\n const m = line.match(/^(#{1,4})\\s+(.+)$/)!;\n const level = m[1].length;\n return `<h${level + 2} class=\"og2-md-heading\">${applyInline(m[2])}</h${level + 2}>`;\n })\n .join('');\n case 'table':\n return renderTable(segment.lines);\n case 'text':\n return `<p>${segment.lines.map((l) => applyInline(l)).join('<br>')}</p>`;\n }\n}\n\n/** Split a table row into cell contents, trimming outer pipes and whitespace. */\nfunction parseTableRow(line: string): string[] {\n const trimmed = line.trim();\n // Strip leading/trailing pipes then split on |\n const inner = trimmed.replace(/^\\|/, '').replace(/\\|$/, '');\n return inner.split('|').map((c) => c.trim());\n}\n\ntype Alignment = 'left' | 'center' | 'right';\n\n/** Parse alignment from separator cells like :---, :---:, ---: */\nfunction parseAlignment(cell: string): Alignment {\n const t = cell.trim();\n const left = t.startsWith(':');\n const right = t.endsWith(':');\n if (left && right) return 'center';\n if (right) return 'right';\n return 'left';\n}\n\n/** Check if a line is a valid table separator (e.g. |---|:---:|---:| ) */\nfunction isSeparatorRow(line: string): boolean {\n const cells = parseTableRow(line);\n return cells.length > 0 && cells.every((c) => /^:?-{1,}:?$/.test(c.trim()));\n}\n\n/**\n * Render a group of table-classified lines into an HTML table.\n * Falls back to text paragraphs if the structure is invalid.\n */\nfunction renderTable(lines: string[]): string {\n // A valid table needs at least 2 rows (header + separator) and\n // the second line must be a separator row\n if (lines.length < 2 || !isSeparatorRow(lines[1])) {\n // Not a valid table — render as plain text\n return `<p>${lines.map((l) => applyInline(l)).join('<br>')}</p>`;\n }\n\n const headerCells = parseTableRow(lines[0]);\n const alignments = parseTableRow(lines[1]).map(parseAlignment);\n const bodyRows = lines.slice(2);\n\n const alignAttr = (i: number) => {\n const a = alignments[i];\n return a && a !== 'left' ? ` style=\"text-align:${a}\"` : '';\n };\n\n const thead = '<thead><tr>' +\n headerCells.map((c, i) => `<th${alignAttr(i)}>${applyInline(c)}</th>`).join('') +\n '</tr></thead>';\n\n let tbody = '';\n if (bodyRows.length > 0) {\n const rows = bodyRows.map((row) => {\n const cells = parseTableRow(row);\n return '<tr>' +\n headerCells.map((_, i) => `<td${alignAttr(i)}>${applyInline(cells[i] ?? '')}</td>`).join('') +\n '</tr>';\n }).join('');\n tbody = `<tbody>${rows}</tbody>`;\n }\n\n return `<table class=\"og2-md-table\">${thead}${tbody}</table>`;\n}\n\nfunction processBlocks(text: string): string {\n const paragraphs = text.split(/\\n{2,}/);\n const result: string[] = [];\n\n for (const para of paragraphs) {\n const trimmed = para.trim();\n if (!trimmed) continue;\n\n // Preserve code block placeholders\n if (/^\\x00CB\\d+\\x00$/.test(trimmed)) {\n result.push(trimmed);\n continue;\n }\n\n const lines = trimmed.split('\\n');\n const segments = segmentLines(lines);\n\n for (const segment of segments) {\n result.push(renderSegment(segment));\n }\n }\n\n return result.join('');\n}\n","const SHADOW_MAP: Record<string, string> = {\n none: 'none',\n soft: '0 2px 8px rgba(0,0,0,0.08)',\n medium: '0 4px 16px rgba(0,0,0,0.12)',\n strong: '0 8px 32px rgba(0,0,0,0.18)',\n 'extra-strong': '0 16px 48px rgba(0,0,0,0.28)',\n};\n\nexport function applyAppearance(\n el: HTMLElement | null,\n appearance: { colors?: Record<string, string>; typography?: Record<string, string | number>; dimensions?: Record<string, number>; shadow?: string } | undefined,\n) {\n if (!el || !appearance) return;\n const set = (prop: string, val: string | number | undefined) => {\n if (val !== undefined && val !== null && val !== '') {\n el.style.setProperty(prop, String(val));\n }\n };\n const { colors, typography, dimensions, shadow } = appearance;\n if (colors) {\n set('--og2-bg', colors.background);\n set('--og2-border', colors.border);\n set('--og2-text', colors.text);\n set('--og2-messages-bg', colors.messagesBackground);\n set('--og2-agent-bubble', colors.agentBubble);\n set('--og2-agent-bubble-text', colors.agentBubbleText);\n set('--og2-user-bubble', colors.userBubble);\n set('--og2-user-bubble-text', colors.userBubbleText);\n set('--og2-user-bubble-border', colors.userBubbleBorder);\n set('--og2-send-bg', colors.sendButtonBackground);\n set('--og2-send-icon', colors.sendButtonIcon);\n set('--og2-send-inactive-bg', colors.sendButtonInactiveBackground);\n }\n if (typography) {\n set('--og2-font', typography.fontFamily);\n set('--og2-font-weight', typography.fontWeight);\n set('--og2-line-height', typography.lineHeight);\n if (typeof typography.fontSize === 'number') set('--og2-font-size', `${typography.fontSize}px`);\n if (typeof typography.headerSize === 'number') set('--og2-header-size', `${typography.headerSize}px`);\n if (typeof typography.letterSpacing === 'number') set('--og2-letter-spacing', `${typography.letterSpacing}px`);\n }\n if (dimensions) {\n if (dimensions.width !== undefined) set('--og2-width', `${dimensions.width}px`);\n if (dimensions.maxHeight !== undefined) set('--og2-height', `${dimensions.maxHeight}px`);\n if (dimensions.borderRadius !== undefined) set('--og2-radius', `${dimensions.borderRadius}px`);\n if (dimensions.padding !== undefined) set('--og2-padding', `${dimensions.padding}px`);\n }\n if (shadow && SHADOW_MAP[shadow]) {\n set('--og2-shadow', SHADOW_MAP[shadow]);\n }\n}\n\nexport function applyBubble(\n el: HTMLElement | null,\n bubble: { background?: string; border?: string; icon?: string; buttonSize?: number; iconSize?: number; right?: number; bottom?: number } | undefined,\n) {\n if (!el || !bubble) return;\n const set = (prop: string, val: string | number | undefined) => {\n if (val !== undefined && val !== null && val !== '') {\n el.style.setProperty(prop, String(val));\n }\n };\n if (bubble.background) set('--og2-bubble-bg', bubble.background);\n if (bubble.border) set('--og2-bubble-border', bubble.border);\n if (bubble.icon) set('--og2-bubble-icon', bubble.icon);\n if (bubble.buttonSize) set('--og2-bubble-size', `${bubble.buttonSize}px`);\n if (bubble.iconSize) set('--og2-bubble-icon-size', `${bubble.iconSize}px`);\n if (bubble.right !== undefined) set('--og2-bubble-right', `${bubble.right}px`);\n if (bubble.bottom !== undefined) set('--og2-bubble-bottom', `${bubble.bottom}px`);\n}\n"],"names":["fileToBase64","file","resolve","reject","reader","result","fetchConfig","apiUrl","productId","url","res","data","err","sendMessage","messages","endUserSessionId","conversationId","attachments","body","identifyEndUser","token","name","resetEndUser","initialState","generateId","widgetReducer","state","action","msgs","last","toolCalls","tc","_a","parseDataStream","callbacks","decoder","buffer","done","value","parts","part","processSSEEvent","message","event","lines","line","payload","chunk","handlers","registerTools","newHandlers","getHandler","hasHandler","KEY_PREFIX","END_USER_SESSION_PREFIX","CONVERSATION_ID_PREFIX","getKey","getEndUserSessionKey","randomId","uuid","_b","getOrCreateEndUserSessionId","key","existing","created","clearEndUserSessionId","saveMessages","cleaned","isStreaming","rest","loadMessages","raw","clearMessages","saveConversationId","loadConversationId","MAX_HEADINGS","MAX_INTERACTIVE","MAX_VISIBLE_TEXT","WIDGET_ROOT_ID","SKIP_TEXT_TAGS","INTERACTIVE_SELECTOR","isVisible","el","node","style","isInsideWidget","getLabel","label","text","truncate","str","max","captureDOM","title","headingEls","headings","h","interactiveEls","interactiveElements","seenLabels","item","parsed","mainEl","visibleText","walkText","child","substituteParams","route","params","escapedKey","tryAnchorClick","path","normalized","anchors","anchor","href","tryFrameworkRouter","win","next","nuxtApp","tryPushState","navigateTo","navigateFn","OurguideClient","options","saved","tools","config","sessionId","first","m","files","trimmed","filesToSend","fileLabel","f","displayContent","fileAttachments","apiMessages","pendingToolCalls","pendingClientCalls","makeCallbacks","allowClientTools","delta","id","args","providerMetadata","nav","error","stream","retConvId","hadError","e","toolResults","contMessages","tr","contStream","msg","_d","_c","escapeHtml","applyInline","_","linkText","renderMarkdown","codeBlocks","processed","lang","code","idx","escaped","langAttr","processBlocks","classifyLine","segmentLines","segments","current","type","renderSegment","segment","l","items","startNum","level","renderTable","parseTableRow","c","parseAlignment","cell","left","right","isSeparatorRow","cells","headerCells","alignments","bodyRows","alignAttr","i","thead","tbody","row","paragraphs","para","SHADOW_MAP","applyAppearance","appearance","set","prop","val","colors","typography","dimensions","shadow","applyBubble","bubble"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/api.ts","../src/state-machine.ts","../src/stream-parser.ts","../src/dom-capture.ts","../src/client-tool-registry.ts","../src/session.ts","../src/navigator.ts","../src/OurguideClient.ts","../src/format-tool-call.ts","../src/markdown.ts","../src/appearance.ts"],"sourcesContent":["export function fileToBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = reader.result as string;\n resolve(result.split(',')[1]); // strip \"data:...;base64,\"\n };\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsDataURL(file);\n });\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\nexport interface AssistantToolCallMessage {\n role: 'assistant';\n content: Array<{\n type: 'tool-call';\n toolCallId: string;\n toolName: string;\n input: Record<string, unknown>;\n providerOptions?: Record<string, unknown>;\n }>;\n}\n\nexport interface ToolResultMessage {\n role: 'tool';\n content: Array<{\n type: 'tool-result';\n toolCallId: string;\n toolName: string;\n output: { type: 'json'; value: Record<string, unknown> };\n }>;\n}\n\nexport type AnyMessage = ChatMessage | AssistantToolCallMessage | ToolResultMessage;\n\nexport interface SendMessageResult {\n stream: ReadableStream<Uint8Array>;\n conversationId: string | null;\n}\n\nexport interface FileAttachment {\n name: string;\n type: string;\n data: string; // base64\n}\n\nexport interface ProductConfig {\n appearance?: {\n colors?: Record<string, string>;\n typography?: Record<string, string | number>;\n dimensions?: Record<string, number>;\n shadow?: string;\n };\n bubble?: {\n background?: string;\n border?: string;\n icon?: string;\n buttonSize?: number;\n iconSize?: number;\n right?: number;\n bottom?: number;\n };\n identity?: {\n name?: string;\n welcomeMessage?: string;\n };\n suggestions?: Array<{ buttonLabel: string; message: string }>;\n}\n\n/**\n * Fetch product config to know which features are enabled.\n */\nexport async function fetchConfig(\n apiUrl: string,\n productId: string\n): Promise<ProductConfig> {\n const url = `${apiUrl}/api/products/${productId}/config`;\n console.log('[Ourguide] fetchConfig HTTP GET', url);\n try {\n const res = await fetch(url, {\n headers: { 'ngrok-skip-browser-warning': 'true' },\n });\n console.log('[Ourguide] fetchConfig HTTP status:', res.status, res.statusText);\n if (!res.ok) {\n console.warn('[Ourguide] fetchConfig non-OK response, returning {}');\n return {};\n }\n const data = await res.json();\n console.log('[Ourguide] fetchConfig raw JSON:', JSON.stringify(data, null, 2));\n return data;\n } catch (err) {\n console.error('[Ourguide] fetchConfig threw:', err);\n return {};\n }\n}\n\n/**\n * Send a chat message and return the raw ReadableStream for parsing.\n * Uses the /api/chat endpoint which returns a Vercel AI SDK data stream.\n */\nexport async function sendMessage(\n apiUrl: string,\n productId: string,\n messages: AnyMessage[],\n endUserSessionId?: string,\n conversationId?: string,\n attachments?: FileAttachment[],\n signal?: AbortSignal,\n): Promise<SendMessageResult> {\n const body: Record<string, unknown> = { productId, messages, endUserSessionId };\n if (conversationId) {\n body.conversationId = conversationId;\n }\n if (attachments && attachments.length > 0) {\n body.attachments = attachments;\n }\n\n const res = await fetch(`${apiUrl}/api/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'ngrok-skip-browser-warning': 'true',\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const data = await res.json().catch(() => ({ error: 'Request failed' }));\n throw new Error(data.error || `HTTP ${res.status}`);\n }\n\n if (!res.body) {\n throw new Error('No response stream available');\n }\n\n return {\n stream: res.body,\n conversationId: res.headers.get('X-Conversation-Id'),\n };\n}\n\nexport async function identifyEndUser(\n apiUrl: string,\n productId: string,\n endUserSessionId: string,\n token: string,\n name?: string\n): Promise<{ stored: boolean } & Record<string, unknown>> {\n const res = await fetch(`${apiUrl}/api/widget/identify`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'ngrok-skip-browser-warning': 'true',\n },\n body: JSON.stringify({ productId, endUserSessionId, token, name }),\n });\n\n const data = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error((data as { error?: string }).error || `HTTP ${res.status}`);\n }\n return data as { stored: boolean } & Record<string, unknown>;\n}\n\nexport async function resetEndUser(\n apiUrl: string,\n productId: string,\n endUserSessionId: string\n): Promise<{ deleted: boolean } & Record<string, unknown>> {\n const res = await fetch(`${apiUrl}/api/widget/reset-user`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'ngrok-skip-browser-warning': 'true',\n },\n body: JSON.stringify({ productId, endUserSessionId }),\n });\n\n const data = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error((data as { error?: string }).error || `HTTP ${res.status}`);\n }\n return data as { deleted: boolean } & Record<string, unknown>;\n}\n","export interface ToolCallInfo {\n id: string;\n name: string;\n args: Record<string, unknown>;\n result?: unknown;\n status: 'calling' | 'done' | 'error';\n /** Provider-specific metadata from the LLM response (e.g. Gemini thought signatures). */\n providerMetadata?: Record<string, unknown>;\n}\n\nexport interface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n toolCalls?: ToolCallInfo[];\n isStreaming?: boolean;\n}\n\nexport interface WidgetState {\n isOpen: boolean;\n messages: Message[];\n isStreaming: boolean;\n error: string | null;\n}\n\nexport type WidgetAction =\n | { type: 'OPEN' }\n | { type: 'CLOSE' }\n | { type: 'LOAD_MESSAGES'; messages: Message[] }\n | { type: 'ADD_USER_MESSAGE'; id: string; content: string }\n | { type: 'START_STREAMING'; id: string }\n | { type: 'APPEND_TEXT'; text: string }\n | { type: 'ADD_TOOL_CALL'; toolCall: ToolCallInfo }\n | { type: 'SET_TOOL_RESULT'; toolCallId: string; result: unknown }\n | { type: 'FINISH_STREAMING' }\n | { type: 'SET_ERROR'; error: string }\n | { type: 'CLEAR_MESSAGES' };\n\nexport const initialState: WidgetState = {\n isOpen: false,\n messages: [],\n isStreaming: false,\n error: null,\n};\n\nfunction generateId(): string {\n return Date.now().toString(36) + Math.random().toString(36).slice(2, 7);\n}\n\nexport { generateId };\n\nexport function widgetReducer(state: WidgetState, action: WidgetAction): WidgetState {\n switch (action.type) {\n case 'OPEN':\n return { ...state, isOpen: true, error: null };\n\n case 'CLOSE':\n return { ...state, isOpen: false };\n\n case 'LOAD_MESSAGES':\n return { ...state, messages: action.messages };\n\n case 'ADD_USER_MESSAGE':\n return {\n ...state,\n error: null,\n messages: [\n ...state.messages,\n { id: action.id, role: 'user', content: action.content },\n ],\n };\n\n case 'START_STREAMING':\n return {\n ...state,\n isStreaming: true,\n error: null,\n messages: [\n ...state.messages,\n { id: action.id, role: 'assistant', content: '', isStreaming: true },\n ],\n };\n\n case 'APPEND_TEXT': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n msgs[msgs.length - 1] = { ...last, content: last.content + action.text };\n }\n return { ...state, messages: msgs };\n }\n\n case 'ADD_TOOL_CALL': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant') {\n const toolCalls = [...(last.toolCalls ?? []), action.toolCall];\n msgs[msgs.length - 1] = { ...last, toolCalls };\n }\n return { ...state, messages: msgs };\n }\n\n case 'SET_TOOL_RESULT': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant' && last.toolCalls) {\n const toolCalls = last.toolCalls.map((tc) =>\n tc.id === action.toolCallId\n ? { ...tc, result: action.result, status: 'done' as const }\n : tc\n );\n msgs[msgs.length - 1] = { ...last, toolCalls };\n }\n return { ...state, messages: msgs };\n }\n\n case 'FINISH_STREAMING': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n // If only tool calls arrived with no text, remove the empty assistant message\n if (!last.content && last.toolCalls?.length) {\n msgs.pop();\n } else {\n msgs[msgs.length - 1] = { ...last, isStreaming: false };\n }\n }\n return { ...state, isStreaming: false, messages: msgs };\n }\n\n case 'SET_ERROR': {\n const msgs = [...state.messages];\n const last = msgs[msgs.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n msgs[msgs.length - 1] = { ...last, isStreaming: false };\n }\n return { ...state, isStreaming: false, error: action.error, messages: msgs };\n }\n\n case 'CLEAR_MESSAGES':\n return { ...state, messages: [], error: null, isStreaming: false };\n\n default:\n return state;\n }\n}\n","/**\n * Lightweight parser for the Vercel AI SDK UI Message Stream protocol (SSE format).\n *\n * Protocol format (AI SDK v6): Server-Sent Events\n * data: {\"type\":\"text-delta\",\"delta\":\"...\",\"id\":\"...\"}\\n\\n\n * data: {\"type\":\"tool-input-start\",\"toolCallId\":\"...\",\"toolName\":\"...\"}\\n\\n\n * data: {\"type\":\"tool-input-delta\",\"toolCallId\":\"...\",\"inputTextDelta\":\"...\"}\\n\\n\n * data: {\"type\":\"tool-input-available\",\"toolCallId\":\"...\",\"toolName\":\"...\",\"input\":{...}}\\n\\n\n * data: {\"type\":\"tool-output-available\",\"toolCallId\":\"...\",\"output\":{...}}\\n\\n\n * data: {\"type\":\"finish\"}\\n\\n\n * data: [DONE]\\n\\n\n */\n\nexport interface StreamCallbacks {\n onTextDelta: (text: string) => void;\n onToolCall: (id: string, name: string, args: Record<string, unknown>, providerMetadata?: Record<string, unknown>) => void;\n onToolResult: (id: string, result: unknown) => void;\n onFinish: () => void;\n onError: (error: string) => void;\n}\n\nexport async function parseDataStream(\n body: ReadableStream<Uint8Array>,\n callbacks: StreamCallbacks\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n buffer += done\n ? decoder.decode()\n : decoder.decode(value, { stream: true });\n\n if (done) break;\n\n // SSE events are separated by double newlines\n const parts = buffer.split('\\n\\n');\n // Keep the last incomplete part in the buffer\n buffer = parts.pop() ?? '';\n\n for (const part of parts) {\n processSSEEvent(part.trim(), callbacks);\n }\n }\n\n // Process any remaining buffer\n if (buffer.trim()) {\n processSSEEvent(buffer.trim(), callbacks);\n }\n\n callbacks.onFinish();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Stream read failed';\n callbacks.onError(message);\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction processSSEEvent(event: string, callbacks: StreamCallbacks): void {\n // SSE lines start with \"data: \"\n const lines = event.split('\\n');\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue;\n\n const payload = line.slice(6); // Remove \"data: \" prefix\n\n // End of stream marker\n if (payload === '[DONE]') return;\n\n try {\n const chunk = JSON.parse(payload) as {\n type: string;\n delta?: string;\n toolCallId?: string;\n toolName?: string;\n input?: Record<string, unknown>;\n inputTextDelta?: string;\n output?: unknown;\n finishReason?: string;\n reason?: string;\n errorText?: string;\n providerMetadata?: Record<string, unknown>;\n };\n\n switch (chunk.type) {\n case 'text-delta':\n if (chunk.delta) {\n callbacks.onTextDelta(chunk.delta);\n }\n break;\n\n // AI SDK v6: tool-input-available fires when tool input is fully parsed\n case 'tool-input-available':\n if (chunk.toolCallId && chunk.toolName) {\n callbacks.onToolCall(\n chunk.toolCallId,\n chunk.toolName,\n (chunk.input as Record<string, unknown>) ?? {},\n chunk.providerMetadata\n );\n }\n break;\n\n // AI SDK v6: tool-output-available fires when tool execution completes\n case 'tool-output-available':\n if (chunk.toolCallId) {\n callbacks.onToolResult(chunk.toolCallId, chunk.output);\n }\n break;\n\n // Legacy event names (AI SDK v5 compat)\n case 'tool-call':\n if (chunk.toolCallId && chunk.toolName) {\n callbacks.onToolCall(\n chunk.toolCallId,\n chunk.toolName,\n (chunk.input as Record<string, unknown>) ?? {}\n );\n }\n break;\n\n case 'tool-result':\n if (chunk.toolCallId) {\n callbacks.onToolResult(chunk.toolCallId, chunk.output);\n }\n break;\n\n case 'error':\n callbacks.onError(chunk.errorText ?? chunk.reason ?? 'Unknown error');\n break;\n\n case 'abort':\n callbacks.onError(chunk.reason ?? 'Response aborted');\n break;\n\n // Ignore: start, finish, text-start, text-end, start-step, finish-step,\n // tool-input-start, tool-input-delta\n default:\n break;\n }\n } catch {\n // Skip malformed JSON silently\n }\n }\n}\n","/**\n * Lightweight DOM snapshot for screen context.\n * Captures just enough for an LLM to understand the current page.\n *\n * Current caps (roughly ~500-1000 tokens per snapshot):\n * - Headings (h1-h3): max 10\n * - Interactive elements (buttons, links, inputs): max 30, labels truncated to 80 chars\n * - Visible text (from <main> or <body>): max 500 chars\n * - Skips: hidden elements, input values (PII), widget's own DOM, scripts/styles/nav/header/footer\n */\n\nexport interface InteractiveElement {\n tag: string;\n text: string;\n type?: string;\n href?: string;\n}\n\nexport interface ScreenContext {\n url: string;\n title: string;\n headings: string[];\n interactiveElements: InteractiveElement[];\n visibleText: string;\n}\n\nconst MAX_HEADINGS = 10;\nconst MAX_INTERACTIVE = 30;\nconst MAX_VISIBLE_TEXT = 500;\n\nconst WIDGET_ROOT_ID = 'og2-widget-root';\n\n/** Tags to skip when extracting visible text */\nconst SKIP_TEXT_TAGS = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'SVG', 'NAV', 'HEADER', 'FOOTER']);\n\n/** Interactive element selectors */\nconst INTERACTIVE_SELECTOR = 'a[href], button, input, select, textarea';\n\nfunction isVisible(el: Element): boolean {\n if (!(el instanceof HTMLElement)) return false;\n // checkVisibility walks the full ancestor chain (Chrome 105+, Firefox 124+)\n if (typeof el.checkVisibility === 'function') {\n return el.checkVisibility({ checkOpacity: false, checkVisibilityCSS: true });\n }\n // Fallback: walk ancestors manually to catch hidden parents\n let node: HTMLElement | null = el;\n while (node) {\n if (node.hidden || node.getAttribute('aria-hidden') === 'true') return false;\n const style = getComputedStyle(node);\n if (style.display === 'none' || style.visibility === 'hidden') return false;\n node = node.parentElement;\n }\n return true;\n}\n\nfunction isInsideWidget(el: Element): boolean {\n return !!el.closest(`#${WIDGET_ROOT_ID}`);\n}\n\nfunction getLabel(el: Element): string {\n if (el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {\n // Try associated label\n if (el.id) {\n const label = document.querySelector(`label[for=\"${CSS.escape(el.id)}\"]`);\n if (label?.textContent?.trim()) return label.textContent.trim();\n }\n // Fallback to aria-label, placeholder, or name\n return (\n el.getAttribute('aria-label') ||\n (el as HTMLInputElement).placeholder ||\n el.getAttribute('name') ||\n ''\n );\n }\n\n // For buttons and links: innerText, aria-label, or title\n const text = (el as HTMLElement).innerText?.trim();\n if (text) return text;\n return el.getAttribute('aria-label') || el.getAttribute('title') || '';\n}\n\nfunction truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 3) + '...';\n}\n\nexport function captureDOM(): ScreenContext {\n // 1. Page metadata — pathname only, avoid leaking host/environment info\n const url = window.location.pathname + window.location.search;\n const title = document.title || '';\n\n // 2. Headings (h1-h3)\n const headingEls = document.querySelectorAll('h1, h2, h3');\n const headings: string[] = [];\n for (const h of headingEls) {\n if (headings.length >= MAX_HEADINGS) break;\n if (isInsideWidget(h) || !isVisible(h)) continue;\n const text = (h as HTMLElement).innerText?.trim();\n if (text && !headings.includes(text)) {\n headings.push(text);\n }\n }\n\n // 3. Interactive elements\n const interactiveEls = document.querySelectorAll(INTERACTIVE_SELECTOR);\n const interactiveElements: InteractiveElement[] = [];\n const seenLabels = new Set<string>();\n\n for (const el of interactiveEls) {\n if (interactiveElements.length >= MAX_INTERACTIVE) break;\n if (isInsideWidget(el) || !isVisible(el)) continue;\n\n const label = getLabel(el);\n if (!label) continue;\n\n // Deduplicate by label+tag\n const key = `${el.tagName}:${label}`;\n if (seenLabels.has(key)) continue;\n seenLabels.add(key);\n\n const item: InteractiveElement = {\n tag: el.tagName.toLowerCase(),\n text: truncate(label, 80),\n };\n\n if (el instanceof HTMLInputElement) {\n item.type = el.type;\n }\n if (el instanceof HTMLAnchorElement && el.href) {\n // Store relative path to avoid leaking full URLs\n try {\n const parsed = new URL(el.href);\n item.href = parsed.pathname + parsed.search;\n } catch {\n item.href = el.getAttribute('href') || undefined;\n }\n }\n\n interactiveElements.push(item);\n }\n\n // 4. Visible text from main content\n const mainEl = document.querySelector('main') || document.body;\n let visibleText = '';\n\n function walkText(node: Node) {\n if (visibleText.length >= MAX_VISIBLE_TEXT) return;\n\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent?.trim();\n if (text) {\n visibleText += (visibleText ? ' ' : '') + text;\n }\n return;\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) return;\n const el = node as Element;\n\n if (SKIP_TEXT_TAGS.has(el.tagName)) return;\n if (isInsideWidget(el)) return;\n if (!isVisible(el)) return;\n\n for (const child of el.childNodes) {\n walkText(child);\n if (visibleText.length >= MAX_VISIBLE_TEXT) return;\n }\n }\n\n walkText(mainEl);\n visibleText = truncate(visibleText.replace(/\\s+/g, ' ').trim(), MAX_VISIBLE_TEXT);\n\n return { url, title, headings, interactiveElements, visibleText };\n}\n","import { captureDOM } from './dom-capture';\n\nexport type ToolHandler = (args: Record<string, unknown>) => Promise<Record<string, unknown>>;\nexport type ToolHandlerMap = Record<string, ToolHandler>;\n\nconst handlers: ToolHandlerMap = {\n capture_screen: async () => captureDOM() as unknown as Record<string, unknown>,\n};\n\nexport function registerTools(newHandlers: ToolHandlerMap): void {\n Object.assign(handlers, newHandlers);\n}\n\nexport function getHandler(name: string): ToolHandler | undefined {\n return handlers[name];\n}\n\nexport function hasHandler(name: string): boolean {\n return Object.hasOwn(handlers, name);\n}\n","import type { Message } from './state-machine';\n\nconst KEY_PREFIX = 'og2-chat-';\nconst END_USER_SESSION_PREFIX = 'og2-enduser-session-';\nconst CONVERSATION_ID_PREFIX = 'og2-conv-';\n\nfunction getKey(productId: string): string {\n return `${KEY_PREFIX}${productId}`;\n}\n\nfunction getEndUserSessionKey(productId: string): string {\n return `${END_USER_SESSION_PREFIX}${productId}`;\n}\n\nfunction randomId(): string {\n const uuid = globalThis.crypto?.randomUUID?.();\n if (uuid) return uuid;\n // Fallback for older environments\n return `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nexport function getOrCreateEndUserSessionId(productId: string): string {\n const key = getEndUserSessionKey(productId);\n try {\n const existing = localStorage.getItem(key);\n if (existing && existing.trim()) return existing;\n const created = `sess_${randomId()}`;\n localStorage.setItem(key, created);\n return created;\n } catch {\n return `sess_${randomId()}`;\n }\n}\n\nexport function clearEndUserSessionId(productId: string): void {\n try {\n localStorage.removeItem(getEndUserSessionKey(productId));\n } catch {\n // fail silently\n }\n}\n\nexport function saveMessages(productId: string, messages: Message[]): void {\n try {\n // Strip streaming flags before persisting\n const cleaned = messages.map(({ isStreaming, ...rest }) => rest);\n sessionStorage.setItem(getKey(productId), JSON.stringify(cleaned));\n } catch {\n // sessionStorage might be unavailable or full — fail silently\n }\n}\n\nexport function loadMessages(productId: string): Message[] {\n try {\n const raw = sessionStorage.getItem(getKey(productId));\n if (!raw) return [];\n return JSON.parse(raw) as Message[];\n } catch {\n return [];\n }\n}\n\nexport function clearMessages(productId: string): void {\n try {\n sessionStorage.removeItem(getKey(productId));\n sessionStorage.removeItem(`${CONVERSATION_ID_PREFIX}${productId}`);\n } catch {\n // fail silently\n }\n}\n\nexport function saveConversationId(productId: string, conversationId: string): void {\n try {\n sessionStorage.setItem(`${CONVERSATION_ID_PREFIX}${productId}`, conversationId);\n } catch {\n // fail silently\n }\n}\n\nexport function loadConversationId(productId: string): string | null {\n try {\n return sessionStorage.getItem(`${CONVERSATION_ID_PREFIX}${productId}`);\n } catch {\n return null;\n }\n}\n\nexport function clearConversationId(productId: string): void {\n try {\n sessionStorage.removeItem(`${CONVERSATION_ID_PREFIX}${productId}`);\n } catch {\n // fail silently\n }\n}\n","/**\n * Substitute dynamic segments in a route pattern with actual values.\n * e.g., \"/users/:userId/profile\" + { userId: \"42\" } => \"/users/42/profile\"\n */\nfunction substituteParams(route: string, params?: Record<string, string>): string {\n if (!params) return route;\n let result = route;\n for (const [key, value] of Object.entries(params)) {\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n result = result.replace(new RegExp(`:${escapedKey}(?!\\\\w)`, 'g'), encodeURIComponent(value));\n }\n return result;\n}\n\nexport type NavigateFn = (path: string) => void;\n\nfunction tryAnchorClick(path: string): boolean {\n const normalized = path.replace(/\\/$/, '') || '/';\n const anchors = document.querySelectorAll('a[href]');\n for (const el of anchors) {\n const anchor = el as HTMLAnchorElement;\n const href = anchor.pathname?.replace(/\\/$/, '') || '/';\n if (anchor.origin === window.location.origin && href === normalized) {\n anchor.click();\n console.log(`[Ourguide] Navigated via anchor click: ${path}`);\n return true;\n }\n }\n return false;\n}\n\nfunction tryFrameworkRouter(path: string): boolean {\n const win = window as unknown as Record<string, unknown>;\n\n // Next.js\n const next = win.next as { router?: { push?: (path: string) => void } } | undefined;\n if (next?.router?.push) {\n next.router.push(path);\n console.log(`[Ourguide] Navigated via Next.js router: ${path}`);\n return true;\n }\n\n // Nuxt / Vue\n const nuxt = win.__NUXT__ as Record<string, unknown> | undefined;\n if (nuxt) {\n const nuxtApp = win.$nuxt as { $router?: { push?: (path: string) => void } } | undefined;\n if (nuxtApp?.$router?.push) {\n nuxtApp.$router.push(path);\n console.log(`[Ourguide] Navigated via Vue/Nuxt router: ${path}`);\n return true;\n }\n }\n\n return false;\n}\n\nfunction tryPushState(path: string): boolean {\n try {\n window.history.pushState({}, '', path);\n window.dispatchEvent(new PopStateEvent('popstate', { state: {} }));\n console.log(`[Ourguide] Navigated via pushState: ${path}`);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Navigate to a route using a four-tier cascade:\n * 1. Consumer-provided navigate fn (e.g. Next.js router.push passed as prop)\n * 2. Click matching anchor in the DOM\n * 3. Auto-detect framework router (Next.js / Nuxt / Vue)\n * 4. pushState + popstate event\n * 5. Hard navigation fallback\n */\nexport async function navigateTo(\n route: string,\n params?: Record<string, string>,\n navigateFn?: NavigateFn,\n): Promise<boolean> {\n const path = substituteParams(route, params);\n\n // Tier 1: explicit navigate prop\n if (navigateFn) {\n navigateFn(path);\n console.log(`[Ourguide] Navigated via navigate prop: ${path}`);\n return true;\n }\n\n // Tier 2: anchor click\n if (tryAnchorClick(path)) return true;\n\n // Tier 3: framework router auto-detection\n if (tryFrameworkRouter(path)) return true;\n\n // Tier 4: pushState\n if (tryPushState(path)) return true;\n\n // Tier 5: hard navigation (always works)\n console.log(`[Ourguide] Navigated via hard navigation: ${path}`);\n window.location.href = path;\n return true;\n}\n","import { sendMessage, fetchConfig, identifyEndUser, resetEndUser, fileToBase64 } from './api';\nimport type { AnyMessage, ChatMessage, FileAttachment, ProductConfig, SendMessageResult } from './api';\nimport { widgetReducer, initialState, generateId } from './state-machine';\nimport type { Message, ToolCallInfo, WidgetState, WidgetAction } from './state-machine';\nimport { parseDataStream } from './stream-parser';\nimport type { StreamCallbacks } from './stream-parser';\nimport { registerTools, hasHandler, getHandler } from './client-tool-registry';\nimport type { ToolHandler, ToolHandlerMap } from './client-tool-registry';\nimport { saveMessages, loadMessages, clearMessages, getOrCreateEndUserSessionId, clearEndUserSessionId, saveConversationId, loadConversationId } from './session';\nimport { renderMarkdown } from './markdown';\nimport { navigateTo } from './navigator';\nimport type { NavigateFn } from './navigator';\nimport { applyAppearance, applyBubble } from './appearance';\n\nexport interface OurguideClientOptions {\n productId: string;\n apiUrl: string;\n}\n\nexport interface OurguideClientCallbacks {\n onStateChange?: (state: WidgetState) => void;\n onMessage?: (message: Message) => void;\n onToolCall?: (toolCall: ToolCallInfo) => void;\n onToolResult?: (toolName: string, result: unknown) => void;\n onError?: (error: string) => void;\n onConfigLoaded?: (config: ProductConfig) => void;\n}\n\nexport type UnsubscribeFn = () => void;\n\nexport class OurguideClient {\n readonly productId: string;\n readonly apiUrl: string;\n\n private state: WidgetState = initialState;\n private conversationId: string | null = null;\n private callbacks: OurguideClientCallbacks = {};\n private listeners = new Set<(state: WidgetState) => void>();\n private abortController: AbortController | null = null;\n private destroyed = false;\n\n constructor(options: OurguideClientOptions) {\n this.productId = options.productId;\n this.apiUrl = options.apiUrl;\n\n this.conversationId = loadConversationId(this.productId);\n const saved = loadMessages(this.productId);\n if (saved.length > 0) {\n this.dispatch({ type: 'LOAD_MESSAGES', messages: saved });\n }\n }\n\n on(callbacks: OurguideClientCallbacks): void {\n this.callbacks = { ...this.callbacks, ...callbacks };\n }\n\n subscribe(listener: (state: WidgetState) => void): UnsubscribeFn {\n this.listeners.add(listener);\n return () => { this.listeners.delete(listener); };\n }\n\n getSnapshot(): WidgetState {\n return this.state;\n }\n\n getState(): WidgetState {\n return this.state;\n }\n\n getMessages(): Message[] {\n return this.state.messages;\n }\n\n dispatch(action: WidgetAction): void {\n if (this.destroyed) return;\n this.state = widgetReducer(this.state, action);\n this.callbacks.onStateChange?.(this.state);\n for (const listener of this.listeners) listener(this.state);\n }\n\n open(): void {\n this.dispatch({ type: 'OPEN' });\n }\n\n close(): void {\n this.dispatch({ type: 'CLOSE' });\n }\n\n registerTools(tools: ToolHandlerMap): void {\n registerTools(tools);\n }\n\n async loadConfig(): Promise<ProductConfig> {\n const config = await fetchConfig(this.apiUrl, this.productId);\n this.callbacks.onConfigLoaded?.(config);\n return config;\n }\n\n async identify(token: string, name?: string): Promise<void> {\n const sessionId = getOrCreateEndUserSessionId(this.productId);\n await identifyEndUser(this.apiUrl, this.productId, sessionId, token, name);\n }\n\n resetUser(): void {\n const sessionId = getOrCreateEndUserSessionId(this.productId);\n resetEndUser(this.apiUrl, this.productId, sessionId).catch(() => {});\n clearEndUserSessionId(this.productId);\n clearMessages(this.productId);\n this.conversationId = null;\n this.dispatch({ type: 'FINISH_STREAMING' });\n this.dispatch({ type: 'CLEAR_MESSAGES' });\n }\n\n destroy(): void {\n this.destroyed = true;\n this.abortController?.abort();\n this.abortController = null;\n this.listeners.clear();\n this.callbacks = {};\n }\n\n revive(): void {\n this.destroyed = false;\n }\n\n newConversation(): { title: string; preview: string; messages: Message[] } | null {\n const msgs = this.state.messages;\n let saved: { title: string; preview: string; messages: Message[] } | null = null;\n if (msgs.length > 0) {\n const first = msgs.find((m) => m.role === 'user');\n saved = {\n title: first ? first.content.slice(0, 30) : 'Conversation',\n preview: msgs[msgs.length - 1].content.slice(0, 50),\n messages: [...msgs],\n };\n }\n clearMessages(this.productId);\n this.conversationId = null;\n this.dispatch({ type: 'CLEAR_MESSAGES' });\n return saved;\n }\n\n async sendMessage(\n text: string,\n files?: File[],\n navigateFn?: NavigateFn,\n ): Promise<void> {\n const trimmed = text.trim();\n const filesToSend = files ? [...files] : [];\n if ((!trimmed && filesToSend.length === 0) || this.state.isStreaming) return;\n\n const fileLabel = filesToSend.length > 0 ? filesToSend.map((f) => `[${f.name}]`).join(' ') : '';\n const displayContent = [trimmed, fileLabel].filter(Boolean).join(' ');\n this.dispatch({ type: 'ADD_USER_MESSAGE', id: generateId(), content: displayContent });\n\n let fileAttachments: FileAttachment[] = [];\n if (filesToSend.length > 0) {\n try {\n fileAttachments = await Promise.all(filesToSend.map(async (f) => ({ name: f.name, type: f.type, data: await fileToBase64(f) })));\n } catch {\n this.dispatch({ type: 'SET_ERROR', error: 'Failed to read attached files' });\n return;\n }\n }\n\n const apiMessages: ChatMessage[] = [\n ...this.state.messages.slice(0, -1).map((m) => ({ role: m.role, content: m.content })),\n { role: 'user' as const, content: trimmed || 'Please review the attached file(s).' },\n ];\n\n this.dispatch({ type: 'START_STREAMING', id: generateId() });\n this.abortController?.abort();\n const ac = new AbortController();\n this.abortController = ac;\n const pendingToolCalls = new Map<string, ToolCallInfo>();\n const pendingClientCalls = new Map<string, { name: string; args: Record<string, unknown>; providerMetadata?: Record<string, unknown> }>();\n\n const makeCallbacks = (allowClientTools: boolean) => ({\n onTextDelta: (delta: string) => this.dispatch({ type: 'APPEND_TEXT', text: delta }),\n onToolCall: (id: string, name: string, args: Record<string, unknown>, providerMetadata?: Record<string, unknown>) => {\n const tc: ToolCallInfo = { id, name, args, status: 'calling', providerMetadata };\n pendingToolCalls.set(id, tc);\n this.dispatch({ type: 'ADD_TOOL_CALL', toolCall: tc });\n this.callbacks.onToolCall?.(tc);\n if (allowClientTools && hasHandler(name)) pendingClientCalls.set(id, { name, args, providerMetadata });\n },\n onToolResult: (id: string, result: unknown) => {\n this.dispatch({ type: 'SET_TOOL_RESULT', toolCallId: id, result });\n const tc = pendingToolCalls.get(id);\n if (tc) this.callbacks.onToolResult?.(tc.name, result);\n if (tc?.name === 'navigate_to_page') {\n const nav = result as { route?: string | null; confidence?: number; params?: Record<string, string> };\n if (nav.route && (nav.confidence ?? 0) >= 0.5) navigateTo(nav.route, nav.params, navigateFn);\n }\n },\n onError: (error: string) => {\n this.dispatch({ type: 'SET_ERROR', error });\n this.callbacks.onError?.(error);\n },\n });\n\n try {\n const endUserSessionId = getOrCreateEndUserSessionId(this.productId);\n const { stream, conversationId: retConvId } = await sendMessage(this.apiUrl, this.productId, apiMessages, endUserSessionId, this.conversationId || undefined, fileAttachments, ac.signal);\n if (retConvId && !this.conversationId) {\n this.conversationId = retConvId;\n saveConversationId(this.productId, retConvId);\n }\n\n let hadError = false;\n await parseDataStream(stream, { ...makeCallbacks(true), onError: (e) => { hadError = true; this.dispatch({ type: 'SET_ERROR', error: e }); this.callbacks.onError?.(e); }, onFinish: () => {} });\n if (hadError || pendingClientCalls.size === 0) { if (!hadError) this.dispatch({ type: 'FINISH_STREAMING' }); this.persistMessages(); return; }\n\n const toolResults: Array<{ toolCallId: string; toolName: string; args: Record<string, unknown>; result: Record<string, unknown>; providerMetadata?: Record<string, unknown> }> = [];\n for (const [id, { name, args, providerMetadata }] of pendingClientCalls) {\n let result: Record<string, unknown>;\n try { result = await getHandler(name)!(args); } catch (err) { result = { status: 'error', error: err instanceof Error ? err.message : 'Handler failed' }; }\n this.dispatch({ type: 'SET_TOOL_RESULT', toolCallId: id, result });\n this.callbacks.onToolResult?.(name, result);\n toolResults.push({ toolCallId: id, toolName: name, args, result, providerMetadata });\n }\n\n const contMessages: AnyMessage[] = [\n ...apiMessages,\n { role: 'assistant', content: toolResults.map((tr) => ({ type: 'tool-call' as const, toolCallId: tr.toolCallId, toolName: tr.toolName, input: tr.args, ...(tr.providerMetadata ? { providerOptions: tr.providerMetadata } : {}) })) },\n { role: 'tool', content: toolResults.map((tr) => ({ type: 'tool-result' as const, toolCallId: tr.toolCallId, toolName: tr.toolName, output: { type: 'json' as const, value: tr.result } })) },\n ];\n const { stream: contStream } = await sendMessage(this.apiUrl, this.productId, contMessages, undefined, this.conversationId || undefined, undefined, ac.signal);\n await parseDataStream(contStream, { ...makeCallbacks(false), onFinish: () => this.dispatch({ type: 'FINISH_STREAMING' }) });\n } catch (err) {\n if (this.destroyed || ac.signal.aborted) return;\n this.dispatch({ type: 'FINISH_STREAMING' });\n const msg = err instanceof Error ? err.message : 'Something went wrong';\n this.dispatch({ type: 'SET_ERROR', error: msg });\n this.callbacks.onError?.(msg);\n }\n\n this.persistMessages();\n }\n\n private persistMessages(): void {\n if (!this.state.isStreaming && this.state.messages.length > 0) {\n saveMessages(this.productId, this.state.messages);\n }\n }\n}\n","import type { ToolCallInfo } from './state-machine';\n\nexport function formatToolCall(tc: ToolCallInfo, awaitingResponse?: boolean): string {\n if (tc.name === 'navigate_to_page') {\n if (tc.status === 'calling') return 'Finding the right page...';\n const result = tc.result as { route?: string | null } | undefined;\n return result?.route ? `Navigated to ${result.route}` : 'No matching page found';\n }\n if (tc.name === 'capture_screen') {\n return (tc.status === 'calling' || awaitingResponse) ? 'Looking at your screen...' : 'Screen captured';\n }\n return tc.name;\n}\n","/**\n * Lightweight markdown-to-HTML renderer for the chat widget.\n * Handles the most common patterns produced by LLMs without external dependencies.\n * ~2-3KB minified.\n */\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/** Apply inline formatting (code, bold, italic, links) to already-escaped text. */\nfunction applyInline(text: string): string {\n let result = text;\n\n // Inline code (must come before bold/italic to avoid conflicts)\n result = result.replace(/`([^`\\n]+)`/g, '<code class=\"og2-md-inline-code\">$1</code>');\n\n // Bold (**text** or __text__)\n result = result.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n result = result.replace(/__(.+?)__/g, '<strong>$1</strong>');\n\n // Italic (*text* or _text_) — avoid matching inside words for underscores\n result = result.replace(/\\*(.+?)\\*/g, '<em>$1</em>');\n result = result.replace(/(?<!\\w)_(.+?)_(?!\\w)/g, '<em>$1</em>');\n\n // Links [text](url) — only allow safe URL schemes\n result = result.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n (_, linkText, url) => {\n const trimmed = url.trim();\n if (/^(https?:\\/\\/|mailto:|\\/|#)/i.test(trimmed)) {\n return `<a class=\"og2-md-link\" href=\"${trimmed}\" target=\"_blank\" rel=\"noopener noreferrer\">${linkText}</a>`;\n }\n return linkText;\n },\n );\n\n return result;\n}\n\nexport function renderMarkdown(text: string): string {\n if (!text) return '';\n\n // 1. Extract fenced code blocks to protect from all processing\n const codeBlocks: string[] = [];\n let processed = text.replace(/```(\\w*)\\n([\\s\\S]*?)```/g, (_, lang, code) => {\n const idx = codeBlocks.length;\n const escaped = escapeHtml(code.replace(/\\n$/, ''));\n const langAttr = lang ? ` data-lang=\"${escapeHtml(lang)}\"` : '';\n codeBlocks.push(\n `<pre class=\"og2-md-pre\"${langAttr}><code class=\"og2-md-code\">${escaped}</code></pre>`,\n );\n return `\\x00CB${idx}\\x00`;\n });\n\n // 2. Escape HTML in remaining text\n processed = escapeHtml(processed);\n\n // 3. Process blocks (detects structure before inline formatting touches markers)\n processed = processBlocks(processed);\n\n // 4. Restore code blocks\n processed = processed.replace(/\\x00CB(\\d+)\\x00/g, (_, idx) => codeBlocks[parseInt(idx)]);\n\n return processed;\n}\n\ntype LineType = 'ul' | 'ol' | 'heading' | 'table' | 'text';\ntype Segment = { type: LineType; lines: string[] };\n\n/** Classify a single line by its markdown structure. */\nfunction classifyLine(line: string): LineType {\n if (/^[\\s]*[-*]\\s/.test(line)) return 'ul';\n if (/^[\\s]*\\d+\\.\\s/.test(line)) return 'ol';\n if (/^#{1,4}\\s+/.test(line)) return 'heading';\n if (/^\\s*\\|/.test(line)) return 'table';\n return 'text';\n}\n\n/** Group consecutive lines of the same type into segments. */\nfunction segmentLines(lines: string[]): Segment[] {\n const segments: Segment[] = [];\n let current: Segment | null = null;\n\n for (const line of lines) {\n const type = classifyLine(line);\n if (current && current.type === type) {\n current.lines.push(line);\n } else {\n if (current) segments.push(current);\n current = { type, lines: [line] };\n }\n }\n if (current) segments.push(current);\n return segments;\n}\n\n/** Render a single segment into HTML. */\nfunction renderSegment(segment: Segment): string {\n switch (segment.type) {\n case 'ul': {\n const items = segment.lines\n .map((l) => `<li>${applyInline(l.replace(/^[\\s]*[-*]\\s/, ''))}</li>`)\n .join('');\n return `<ul class=\"og2-md-list\">${items}</ul>`;\n }\n case 'ol': {\n const items = segment.lines\n .map((l) => `<li>${applyInline(l.replace(/^[\\s]*\\d+\\.\\s/, ''))}</li>`)\n .join('');\n const startNum = segment.lines[0].match(/^[\\s]*(\\d+)\\./)?.[1] ?? '1';\n const startAttr = startNum !== '1' ? ` start=\"${startNum}\"` : '';\n return `<ol class=\"og2-md-list\"${startAttr}>${items}</ol>`;\n }\n case 'heading':\n return segment.lines\n .map((line) => {\n const m = line.match(/^(#{1,4})\\s+(.+)$/)!;\n const level = m[1].length;\n return `<h${level + 2} class=\"og2-md-heading\">${applyInline(m[2])}</h${level + 2}>`;\n })\n .join('');\n case 'table':\n return renderTable(segment.lines);\n case 'text':\n return `<p>${segment.lines.map((l) => applyInline(l)).join('<br>')}</p>`;\n }\n}\n\n/** Split a table row into cell contents, trimming outer pipes and whitespace. */\nfunction parseTableRow(line: string): string[] {\n const trimmed = line.trim();\n // Strip leading/trailing pipes then split on |\n const inner = trimmed.replace(/^\\|/, '').replace(/\\|$/, '');\n return inner.split('|').map((c) => c.trim());\n}\n\ntype Alignment = 'left' | 'center' | 'right';\n\n/** Parse alignment from separator cells like :---, :---:, ---: */\nfunction parseAlignment(cell: string): Alignment {\n const t = cell.trim();\n const left = t.startsWith(':');\n const right = t.endsWith(':');\n if (left && right) return 'center';\n if (right) return 'right';\n return 'left';\n}\n\n/** Check if a line is a valid table separator (e.g. |---|:---:|---:| ) */\nfunction isSeparatorRow(line: string): boolean {\n const cells = parseTableRow(line);\n return cells.length > 0 && cells.every((c) => /^:?-{1,}:?$/.test(c.trim()));\n}\n\n/**\n * Render a group of table-classified lines into an HTML table.\n * Falls back to text paragraphs if the structure is invalid.\n */\nfunction renderTable(lines: string[]): string {\n // A valid table needs at least 2 rows (header + separator) and\n // the second line must be a separator row\n if (lines.length < 2 || !isSeparatorRow(lines[1])) {\n // Not a valid table — render as plain text\n return `<p>${lines.map((l) => applyInline(l)).join('<br>')}</p>`;\n }\n\n const headerCells = parseTableRow(lines[0]);\n const alignments = parseTableRow(lines[1]).map(parseAlignment);\n const bodyRows = lines.slice(2);\n\n const alignAttr = (i: number) => {\n const a = alignments[i];\n return a && a !== 'left' ? ` style=\"text-align:${a}\"` : '';\n };\n\n const thead = '<thead><tr>' +\n headerCells.map((c, i) => `<th${alignAttr(i)}>${applyInline(c)}</th>`).join('') +\n '</tr></thead>';\n\n let tbody = '';\n if (bodyRows.length > 0) {\n const rows = bodyRows.map((row) => {\n const cells = parseTableRow(row);\n return '<tr>' +\n headerCells.map((_, i) => `<td${alignAttr(i)}>${applyInline(cells[i] ?? '')}</td>`).join('') +\n '</tr>';\n }).join('');\n tbody = `<tbody>${rows}</tbody>`;\n }\n\n return `<table class=\"og2-md-table\">${thead}${tbody}</table>`;\n}\n\nfunction processBlocks(text: string): string {\n const paragraphs = text.split(/\\n{2,}/);\n const result: string[] = [];\n\n for (const para of paragraphs) {\n const trimmed = para.trim();\n if (!trimmed) continue;\n\n // Preserve code block placeholders\n if (/^\\x00CB\\d+\\x00$/.test(trimmed)) {\n result.push(trimmed);\n continue;\n }\n\n const lines = trimmed.split('\\n');\n const segments = segmentLines(lines);\n\n for (const segment of segments) {\n result.push(renderSegment(segment));\n }\n }\n\n return result.join('');\n}\n","const SHADOW_MAP: Record<string, string> = {\n none: 'none',\n soft: '0 2px 8px rgba(0,0,0,0.08)',\n medium: '0 4px 16px rgba(0,0,0,0.12)',\n strong: '0 8px 32px rgba(0,0,0,0.18)',\n 'extra-strong': '0 16px 48px rgba(0,0,0,0.28)',\n};\n\nexport function applyAppearance(\n el: HTMLElement | null,\n appearance: { colors?: Record<string, string>; typography?: Record<string, string | number>; dimensions?: Record<string, number>; shadow?: string } | undefined,\n) {\n if (!el || !appearance) return;\n const set = (prop: string, val: string | number | undefined) => {\n if (val !== undefined && val !== null && val !== '') {\n el.style.setProperty(prop, String(val));\n }\n };\n const { colors, typography, dimensions, shadow } = appearance;\n if (colors) {\n set('--og2-bg', colors.background);\n set('--og2-border', colors.border);\n set('--og2-text', colors.text);\n set('--og2-messages-bg', colors.messagesBackground);\n set('--og2-agent-bubble', colors.agentBubble);\n set('--og2-agent-bubble-text', colors.agentBubbleText);\n set('--og2-user-bubble', colors.userBubble);\n set('--og2-user-bubble-text', colors.userBubbleText);\n set('--og2-user-bubble-border', colors.userBubbleBorder);\n set('--og2-send-bg', colors.sendButtonBackground);\n set('--og2-send-icon', colors.sendButtonIcon);\n set('--og2-send-inactive-bg', colors.sendButtonInactiveBackground);\n }\n if (typography) {\n set('--og2-font', typography.fontFamily);\n set('--og2-font-weight', typography.fontWeight);\n set('--og2-line-height', typography.lineHeight);\n if (typeof typography.fontSize === 'number') set('--og2-font-size', `${typography.fontSize}px`);\n if (typeof typography.headerSize === 'number') set('--og2-header-size', `${typography.headerSize}px`);\n if (typeof typography.letterSpacing === 'number') set('--og2-letter-spacing', `${typography.letterSpacing}px`);\n }\n if (dimensions) {\n if (dimensions.width !== undefined) set('--og2-width', `${dimensions.width}px`);\n if (dimensions.maxHeight !== undefined) set('--og2-height', `${dimensions.maxHeight}px`);\n if (dimensions.borderRadius !== undefined) set('--og2-radius', `${dimensions.borderRadius}px`);\n if (dimensions.padding !== undefined) set('--og2-padding', `${dimensions.padding}px`);\n }\n if (shadow && SHADOW_MAP[shadow]) {\n set('--og2-shadow', SHADOW_MAP[shadow]);\n }\n}\n\nexport function applyBubble(\n el: HTMLElement | null,\n bubble: { background?: string; border?: string; icon?: string; buttonSize?: number; iconSize?: number; right?: number; bottom?: number } | undefined,\n) {\n if (!el || !bubble) return;\n const set = (prop: string, val: string | number | undefined) => {\n if (val !== undefined && val !== null && val !== '') {\n el.style.setProperty(prop, String(val));\n }\n };\n if (bubble.background) set('--og2-bubble-bg', bubble.background);\n if (bubble.border) set('--og2-bubble-border', bubble.border);\n if (bubble.icon) set('--og2-bubble-icon', bubble.icon);\n if (bubble.buttonSize) set('--og2-bubble-size', `${bubble.buttonSize}px`);\n if (bubble.iconSize) set('--og2-bubble-icon-size', `${bubble.iconSize}px`);\n if (bubble.right !== undefined) set('--og2-bubble-right', `${bubble.right}px`);\n if (bubble.bottom !== undefined) set('--og2-bubble-bottom', `${bubble.bottom}px`);\n}\n"],"names":["fileToBase64","file","resolve","reject","reader","result","fetchConfig","apiUrl","productId","url","res","data","err","sendMessage","messages","endUserSessionId","conversationId","attachments","signal","body","identifyEndUser","token","name","resetEndUser","initialState","generateId","widgetReducer","state","action","msgs","last","toolCalls","tc","_a","parseDataStream","callbacks","decoder","buffer","done","value","parts","part","processSSEEvent","message","event","lines","line","payload","chunk","MAX_HEADINGS","MAX_INTERACTIVE","MAX_VISIBLE_TEXT","WIDGET_ROOT_ID","SKIP_TEXT_TAGS","INTERACTIVE_SELECTOR","isVisible","el","node","style","isInsideWidget","getLabel","label","text","_b","truncate","str","max","captureDOM","title","headingEls","headings","h","interactiveEls","interactiveElements","seenLabels","key","item","parsed","mainEl","visibleText","walkText","child","handlers","registerTools","newHandlers","getHandler","hasHandler","KEY_PREFIX","END_USER_SESSION_PREFIX","CONVERSATION_ID_PREFIX","getKey","getEndUserSessionKey","randomId","uuid","getOrCreateEndUserSessionId","existing","created","clearEndUserSessionId","saveMessages","cleaned","isStreaming","rest","loadMessages","raw","clearMessages","saveConversationId","loadConversationId","substituteParams","route","params","escapedKey","tryAnchorClick","path","normalized","anchors","anchor","href","tryFrameworkRouter","win","next","nuxtApp","tryPushState","navigateTo","navigateFn","OurguideClient","options","saved","listener","tools","config","sessionId","first","m","files","trimmed","filesToSend","fileLabel","f","displayContent","fileAttachments","apiMessages","ac","pendingToolCalls","pendingClientCalls","makeCallbacks","allowClientTools","delta","id","args","providerMetadata","nav","error","stream","retConvId","hadError","e","toolResults","_c","contMessages","tr","contStream","msg","_e","_d","formatToolCall","awaitingResponse","escapeHtml","applyInline","_","linkText","renderMarkdown","codeBlocks","processed","lang","code","idx","escaped","langAttr","processBlocks","classifyLine","segmentLines","segments","current","type","renderSegment","segment","l","items","startNum","level","renderTable","parseTableRow","c","parseAlignment","cell","left","right","isSeparatorRow","cells","headerCells","alignments","bodyRows","alignAttr","i","thead","tbody","row","paragraphs","para","SHADOW_MAP","applyAppearance","appearance","set","prop","val","colors","typography","dimensions","shadow","applyBubble","bubble"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -52,6 +52,8 @@ export declare interface FileAttachment {
52
52
 
53
53
  export declare function fileToBase64(file: File): Promise<string>;
54
54
 
55
+ export declare function formatToolCall(tc: ToolCallInfo, awaitingResponse?: boolean): string;
56
+
55
57
  export declare function generateId(): string;
56
58
 
57
59
  export declare function getHandler(name: string): ToolHandler | undefined;
@@ -113,8 +115,13 @@ export declare class OurguideClient {
113
115
  private state;
114
116
  private conversationId;
115
117
  private callbacks;
118
+ private listeners;
119
+ private abortController;
120
+ private destroyed;
116
121
  constructor(options: OurguideClientOptions);
117
122
  on(callbacks: OurguideClientCallbacks): void;
123
+ subscribe(listener: (state: WidgetState) => void): UnsubscribeFn;
124
+ getSnapshot(): WidgetState;
118
125
  getState(): WidgetState;
119
126
  getMessages(): Message[];
120
127
  dispatch(action: WidgetAction): void;
@@ -124,6 +131,8 @@ export declare class OurguideClient {
124
131
  loadConfig(): Promise<ProductConfig>;
125
132
  identify(token: string, name?: string): Promise<void>;
126
133
  resetUser(): void;
134
+ destroy(): void;
135
+ revive(): void;
127
136
  newConversation(): {
128
137
  title: string;
129
138
  preview: string;
@@ -204,7 +213,7 @@ export declare interface ScreenContext {
204
213
  * Send a chat message and return the raw ReadableStream for parsing.
205
214
  * Uses the /api/chat endpoint which returns a Vercel AI SDK data stream.
206
215
  */
207
- export declare function sendMessage(apiUrl: string, productId: string, messages: AnyMessage[], endUserSessionId?: string, conversationId?: string, attachments?: FileAttachment[]): Promise<SendMessageResult>;
216
+ export declare function sendMessage(apiUrl: string, productId: string, messages: AnyMessage[], endUserSessionId?: string, conversationId?: string, attachments?: FileAttachment[], signal?: AbortSignal): Promise<SendMessageResult>;
208
217
 
209
218
  export declare interface SendMessageResult {
210
219
  stream: ReadableStream<Uint8Array>;
@@ -258,6 +267,8 @@ export declare interface ToolResultMessage {
258
267
  }>;
259
268
  }
260
269
 
270
+ export declare type UnsubscribeFn = () => void;
271
+
261
272
  export declare type WidgetAction = {
262
273
  type: 'OPEN';
263
274
  } | {