@marketrix.ai/widget 4.0.125 → 4.0.127

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.
@@ -63,4 +63,3 @@ export declare const SlackCommandLogStatusSchema: z.ZodEnum<{
63
63
  completed: "completed";
64
64
  failed: "failed";
65
65
  }>;
66
- export type SlackCommandLogStatus = z.infer<typeof SlackCommandLogStatusSchema>;
@@ -256,7 +256,6 @@ export declare const WidgetSettingsWriteSchema: z.ZodObject<{
256
256
  chip_text: z.ZodString;
257
257
  }, z.core.$strip>>;
258
258
  }, z.core.$strip>;
259
- export type WidgetSettingsWriteData = z.infer<typeof WidgetSettingsWriteSchema>;
260
259
  export declare const WidgetEntitySchema: z.ZodObject<{
261
260
  id: z.ZodNumber;
262
261
  created_at: z.ZodCoercedDate<unknown>;
package/dist/widget.mjs CHANGED
@@ -17,7 +17,7 @@ return v(zs,{toast:e,className:"mtx-toast",render:/* @__PURE__ */b(bc,{align:"ce
17
17
  /* @__PURE__ */b(lc,{src:Za,alt:"",size:28,rounded:"pill"}),
18
18
  /* @__PURE__ */v(vc,{grow:!0,minWidth:"0",children:[/* @__PURE__ */b(Ys,{render:/* @__PURE__ */b(Mc,{as:"span",block:!0,inheritColor:!0,truncate:!0,weight:"medium",style:{fontSize:"13px",color:t.titleColor,...e.actionProps&&{whiteSpace:"normal"}}})}),null!=e.description&&/* @__PURE__ */b(Vs,{render:/* @__PURE__ */b(Mc,{as:"span",block:!0,inheritColor:!0,truncate:!0,style:{fontSize:"12px",color:t.bodyColor,opacity:.8}})})]}),e.actionProps&&/* @__PURE__ */b(ea,{render:/* @__PURE__ */b(pc,{variant:"ghost",shape:"pill",size:"sm",style:{color:t.titleColor,backgroundColor:t.actionBackground,border:t.border}})}),
19
19
  /* @__PURE__ */b(Qs,{onMouseDown:e=>e.preventDefault(),render:/* @__PURE__ */b(kc,{label:"Dismiss",size:"xs",tone:"inherit",style:{color:t.closeColor,padding:"2px"}}),children:/* @__PURE__ */b(Sc,{name:"closeSmall",size:12})})]},e.id)})},Rc=({children:e,container:t,offsetBottom:n=20})=>/* @__PURE__ */v(Zi,{children:[e,/* @__PURE__ */b(pa,{container:t??void 0,children:/* @__PURE__ */b(Ss,{className:"mtx-toast-viewport",style:{zIndex:2147483004,bottom:`${n}px`},children:/* @__PURE__ */b(Tc,{})})})]}),Oc=({error:e,onClearError:t,onRetry:n,greeting:r,greetingBody:o,onGreetingDismiss:i})=>{const{add:s,close:c}=Ja();return a(()=>{null!=e?s({id:"error",type:"error",title:e,timeout:0,priority:"high",onClose:t,...n&&{actionProps:{children:"Retry",onClick:n}}}):c("error")},[e,n,s,c,t]),a(()=>{r?s({id:"greeting",type:"info",title:r,description:o,timeout:8e3,onClose:i}):c("greeting")},[r,o,s,c,i]),null};function Ac(e){const t=d(e);return t.current=e,t}var _c=e=>e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement,Dc=e=>e instanceof HTMLButtonElement||"button"===e.getAttribute("role");function Pc(e,t){const n=1===t?"ArrowDown":"ArrowUp",r=e.selectedIndex+t;return r<0||r>=e.options.length?`${n}: already at ${1===t?"last":"first"} option`:(e.selectedIndex=r,e.dispatchEvent(new Event("change",{bubbles:!0})),`${n}: selected "${e.options[r]?.text??""}"`)}function Nc(e,t){const n=e.value,r=e.selectionStart??n.length,o=e.selectionEnd??n.length;let i,s;if(r!==o)i=n.slice(0,r)+n.slice(o),s=r;else if("Backspace"===t&&r>0)i=n.slice(0,r-1)+n.slice(o),s=r-1;else{if(!("Delete"===t&&r<n.length))return`${t}: ${"Backspace"===t?"cursor at start":"cursor at end"}, nothing to delete`;i=n.slice(0,r)+n.slice(r+1),s=r}return function(e,t,n){Lc(e,t),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("change",{bubbles:!0})),e.setSelectionRange(n,n)}(e,i,s),`${t}: deleted character, value is now "${i}"`}function Lc(e,t){const n=Object.getOwnPropertyDescriptor(e instanceof HTMLTextAreaElement?HTMLTextAreaElement.prototype:HTMLInputElement.prototype,"value")?.set;n?n.call(e,t):e.value=t}var Fc=e=>({success:!0,data:{text:e}}),zc=e=>({success:!0,data:e}),$c=e=>({success:!1,error:e}),Bc=(e,t)=>({success:!0,data:{text:e},afterResponseAttempt:t}),Wc="finish",Uc=new class{tools={navigate:{label:"Navigating",run:e=>this.navigate(e)},search_web:{label:"Searching",run:e=>this.search(e)},click_element:{label:"Clicking element",waitForUser:!0,run:e=>this.clickElement(e)},type_text:{label:"Typing text",waitForUser:!0,run:e=>this.typeText(e)},scroll:{label:"Scrolling",run:e=>this.scroll(e)},scroll_to_text:{label:"Scrolling to text",run:e=>this.scrollToText(e)},extract:{label:"Extracting content",run:e=>this.extract(e)},go_back:{label:"Going back",run:()=>this.goBack()},wait_seconds:{label:"Waiting",run:e=>this.wait(e)},select_dropdown:{label:"Selecting option",waitForUser:!0,run:e=>this.selectDropdownOption(e)},get_dropdown_options:{label:"Reading dropdown options",run:e=>this.getDropdownOptions(e)},send_keys:{label:"Pressing key",waitForUser:!0,run:e=>this.sendKeys(e)},close_tab:{label:"Closing tab",run:()=>this.closeTab()},[Wc]:{label:"Done",run:e=>this.done(e)},get_html:{label:"Reading the page",run:()=>this.getHtml()},get_screenshot:{label:"Taking screenshot",run:()=>this.getScreenshot()}};element(e){if(void 0===e)throw new Error("Index required");const{element:t,error:n}=_r.getValidatedElement(e);if(!t)throw new Error(n||`Element ${e} not found`);return t}selectElement(e){const t=this.element(e);if(!(t instanceof HTMLSelectElement))throw new Error(`Element ${e} is not a select element`);return t}getFriendlyToolName(e){return this.tools[e]?.label??e}isWaitForUserTool(e){return!!this.tools[e]?.waitForUser}async executeTool(e,t,n,r=""){const o=t,i=this.tools[e];try{return"show"===n&&i?.waitForUser&&void 0!==o.index&&await Lr.showToolAction({element:this.element(o.index),explanation:r||`Execute ${e}`,browserToolName:e,isClickAction:"click_element"===e}),i?await i.run(o):$c(`Unknown tool: ${e}`)}catch(s){return $c(Oe(s))}}navigate(e){const t=(e=>{if(!e)return null;try{const t=new URL(e,window.location.href);return"http:"===t.protocol||"https:"===t.protocol?t.href:null}catch{return null}})(e.url);return t?e.new_tab?window.open(t,"_blank")?Fc(`Opened ${t} in new tab`):$c("The browser blocked opening a new tab"):Bc(`Navigating to ${t}`,()=>{window.location.href=t}):$c("An http(s) URL is required")}search(e){if(!e.query)return $c("Query is required");const t=e.engine||"duckduckgo",n=encodeURIComponent(e.query);let r=`https://duckduckgo.com/?q=${n}`;return"google"===t&&(r=`https://www.google.com/search?q=${n}`),"bing"===t&&(r=`https://www.bing.com/search?q=${n}`),Bc(`Searching for "${e.query}" on ${t}`,()=>{window.location.href=r})}async clickElement(e){const t=this.element(e.index);return t.scrollIntoView({behavior:"smooth",block:"center"}),await new Promise(e=>setTimeout(e,100)),Bc(`Clicking element ${e.index}`,()=>t.click())}typeText(e){if(void 0===e.text)return $c("Text required");const t=!1!==e.clear,n=this.element(e.index);if(_c(n))n.focus(),Lc(n,t?e.text:n.value+e.text),n.dispatchEvent(new InputEvent("input",{bubbles:!0,cancelable:!0,inputType:"insertText",data:e.text})),n.dispatchEvent(new Event("change",{bubbles:!0})),n.dispatchEvent(new Event("blur",{bubbles:!0}));else if(n.isContentEditable){n.focus();const r=window.getSelection();if(t?r?.selectAllChildren(n):r?.collapse(n,n.childNodes.length),!document.execCommand("insertText",!1,e.text))return $c(`Could not insert text into element ${e.index}`)}else"value"in n?(n.value=e.text,n.dispatchEvent(new Event("input",{bubbles:!0})),n.dispatchEvent(new Event("change",{bubbles:!0}))):(n.textContent=e.text,n.dispatchEvent(new Event("input",{bubbles:!0})));return Fc(`Typed text into element ${e.index}`)}scroll(e){const t=.8*window.innerHeight;switch(e.direction){case"down":window.scrollBy({top:t,behavior:"smooth"});break;case"up":window.scrollBy({top:-t,behavior:"smooth"});break;case"left":window.scrollBy({left:-t,behavior:"smooth"});break;case"right":window.scrollBy({left:t,behavior:"smooth"});break;default:return $c("Invalid direction")}return Fc(`Scrolled ${e.direction}`)}scrollToText(e){if(!e.text)return $c("Text required");const t=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT);let n;for(;n=t.nextNode();)if(n.textContent?.includes(e.text))return n.parentElement?.scrollIntoView({behavior:"smooth",block:"center"}),Fc(`Scrolled to "${e.text}"`);return $c(`Text "${e.text}" not found`)}extract(e){const t=!1!==e.extract_links,n={title:document.title,url:window.location.href,text:document.body.innerText.slice(0,1e4),links:t?Array.from(document.querySelectorAll("a[href]")).slice(0,100).map(e=>({text:e.textContent?.trim()||"",href:e.getAttribute("href")})):[]};return zc(n)}goBack(){return window.history.length<=1?$c("No history"):Bc("Going back",()=>window.history.back())}async wait({seconds:e}){return void 0===e?$c("Seconds required"):(await new Promise(t=>setTimeout(t,1e3*e)),Fc(`Waited ${e}s`))}selectDropdownOption(e){if(!e.option)return $c("Option required");const t=this.selectElement(e.index),n=Array.from(t.options).find(t=>t.value===e.option||t.text===e.option);return n?(t.value=n.value,t.dispatchEvent(new Event("change",{bubbles:!0})),Fc(`Selected ${e.option}`)):$c(`Option ${e.option} not found`)}getDropdownOptions(e){const t=Array.from(this.selectElement(e.index).options).map(e=>({value:e.value,text:e.text}));return zc({options:t})}sendKeys(e){if(!e.keys)return $c("Keys required");const t=this.element(e.index);t.focus(),t.dispatchEvent(new KeyboardEvent("keydown",{key:e.keys,bubbles:!0,cancelable:!0})),t.dispatchEvent(new KeyboardEvent("keyup",{key:e.keys,bubbles:!0,cancelable:!0}));const n=function(e,t){switch(t){case"Tab":case"Shift+Tab":{const n="Tab"===t?1:-1,r=Tr(document),o=r.indexOf(e),i=-1===o?void 0:r[o+n];return i?(i.focus(),`${t}: moved focus to ${i.tagName.toLowerCase()}${i.id?`#${i.id}`:""}`):`${t}: no ${n>0?"next":"previous"} focusable element`}case"Enter":if(Dc(e))return e.click(),"Enter: clicked button";if(_c(e)){const t=e.closest("form");if(t){const e=t.querySelector('button[type="submit"], input[type="submit"]');return e?(e.click(),"Enter: clicked form submit button"):(t.requestSubmit(),"Enter: submitted form")}}return e instanceof HTMLAnchorElement?(e.click(),"Enter: clicked link"):"Enter: dispatched event";case"Escape":return e.blur(),document.dispatchEvent(new KeyboardEvent("keydown",{key:"Escape",bubbles:!0,cancelable:!0})),"Escape: blurred element and dispatched to document";case" ":case"Space":return e instanceof HTMLInputElement&&("checkbox"===e.type||"radio"===e.type)?(e.click(),`Space: toggled ${e.type}`):Dc(e)?(e.click(),"Space: clicked button"):"Space: dispatched event";case"ArrowDown":return e instanceof HTMLSelectElement?Pc(e,1):"ArrowDown: dispatched event";case"ArrowUp":return e instanceof HTMLSelectElement?Pc(e,-1):"ArrowUp: dispatched event";case"Home":return _c(e)?(e.setSelectionRange(0,0),"Home: moved cursor to start"):"Home: dispatched event";case"End":if(_c(e)){const t=e.value.length;return e.setSelectionRange(t,t),"End: moved cursor to end"}return"End: dispatched event";case"Backspace":return _c(e)?Nc(e,"Backspace"):"Backspace: dispatched event";case"Delete":return _c(e)?Nc(e,"Delete"):"Delete: dispatched event";default:return null}}(t,e.keys);return Fc(n||`Sent keys ${e.keys}`)}closeTab(){return window.close(),window.closed?Fc("Tab closed"):$c("The browser refused to close a tab this script did not open")}done(e){return Fc(e.message||"Task ended")}getHtml(){return Fc(_r.reindexAndSnapshot())}async getScreenshot(){const e=br();if(!e)return $c("The visitor is not sharing their screen.");const t=document.createElement("video");try{t.srcObject=e,t.autoplay=!0,t.style.display="none",document.body.appendChild(t),await new Promise((e,n)=>{const r=setTimeout(()=>n(/* @__PURE__ */new Error("Screen capture produced no frame")),5e3);t.onloadeddata=()=>{clearTimeout(r),e()},t.onerror=()=>{clearTimeout(r),n(/* @__PURE__ */new Error("Screen capture failed"))}});const n=document.createElement("canvas");n.width=t.videoWidth,n.height=t.videoHeight;const r=n.getContext("2d");return r?(r.drawImage(t,0,0),Fc(n.toDataURL("image/jpeg",.75))):$c("Could not read the shared screen: the browser refused a 2d canvas context.")}finally{t.remove()}}},Hc={show:"Show",tell:"Tell",do:"Do"},jc=e=>Hc[e];function qc(e,t){for(let n=e.length-1;n>=0;n--){const r=e[n];if(void 0!==r&&t(r))return n}return-1}function Vc({messages:e,isTaskRunning:t,currentMode:n}){const r=e=>"agent"===e.sender&&!e.isSystemMessage&&!e.isScreenAccessRequest&&!e.taskStatus,o=e=>e.isPlaceholder&&void 0===e.mode||e.mode===n,i=[];!t||"show"!==n&&"do"!==n||i.push(e=>r(e)&&o(e)&&!!e.isPlaceholder,e=>r(e)&&o(e)),i.push(e=>r(e)&&!!e.isPlaceholder,r);const s=qc(e,e=>"agent"===e.sender&&!!e.taskStatus)+1,a=e.slice(s);for(const c of i){const e=qc(a,c),t=e>=0?a[e]:void 0;if(t)return{index:s+e,message:t}}return Ae(`[MessageFinder] No message found for progress update: totalMessages=${e.length} isTaskRunning=${t} currentMode=${n}`),null}var Yc=e=>e.replace(/\(?cancelled by cleanup\)?/gi,"").trim();function Kc(e,t,n){const r=t>=0?e.parts[t]:void 0;if(!r)return e;const o=[...e.parts];return o[t]={...r,...n},{...e,parts:o}}var Xc=(e,t)=>e.parts.findIndex(e=>"progress"===e.type&&"in_progress"===e.status&&e.browserToolName===t);function Gc(e,t,n,r={}){return{id:`${e}-${globalThis.crypto.randomUUID()}`,sender:t,timestamp:/* @__PURE__ */new Date,parts:n?[{type:"text",content:n}]:[],...r}}var Jc=(e,t,n="user-message")=>Gc(n,"user",e.trim(),{mode:t}),Zc=e=>Gc("agent-message","agent",e.trim()),Qc=(e,t)=>Gc(t,"agent",e,{isSystemMessage:!0}),el="I'm sorry, I encountered an error processing your request. Please try again.",tl=e=>({state:e,effects:[]});function nl(e,t,n,r,o,i,s){const a=Vc({messages:e,isTaskRunning:t,currentMode:n});if(!a)return e;let c=a.message;if("failed"===i?c=function(e,t,n){const r=Xc(e,t),o=r>=0?e.parts[r]:void 0;if(!o)return e;const i=Yc(o.content),s=Yc(n);return Kc(e,r,{status:"failed",content:s?`${i} (${s})`:i})}(c,r,s||""):"finish"!==r&&(c="in_progress"===i?function(e,t,n){const r=Yc(n),o=Xc(e,t);return o>=0?Kc(e,o,{content:r}):{...e,parts:[...e.parts,{type:"progress",content:r,status:"in_progress",browserToolName:t}]}}(c,r,o||Uc.getFriendlyToolName(r)):((e,t)=>Kc(e,Xc(e,t),{status:"completed"}))(c,r)),t&&("show"===n||"do"===n)){const e="in_progress"===i&&"show"===n&&Uc.isWaitForUserTool(r);c={...c,placeholderState:e?"waiting-for-user":"thinking"}}const l=[...e];return l[a.index]=c,l}var rl=(e,t)=>"running"===e.task.phase?e.task.mode??t:t,ol=e=>({...e,isPlaceholder:!1}),il=e=>"stopped"===e.phase?e:{phase:"idle"};function sl(e,t,n){const r=Vc({messages:e.messages,isTaskRunning:"running"===e.task.phase,currentMode:rl(e,t)}),o=[...e.messages];return r&&(o[r.index]=ol(n(r.message))),{messages:o,task:il(e.task)}}var al={completed:"done",failed:"failed",stopped:"stopped"};function cl(e,t,n,r){const o=e.messages.map(e=>{if(e.id!==t)return e;const o=[...e.parts],i=o[o.length-1],s="text"===i?.type&&!0===i.streaming;if("text"===i?.type&&!s&&i.content===n)return e;const a={type:"text",content:r&&s?i.content+n:n,...r&&{streaming:!0}};return s?o[o.length-1]=a:o.push(a),{...e,isPlaceholder:!1,placeholderState:void 0,parts:o}});return{...e,messages:o}}var ll=(e,t)=>({...e,parts:[...e.parts,{type:"text",content:t}]}),ul=(e,t)=>({...ol(ll(e,t)),placeholderState:void 0,taskStatus:"failed"});function dl(e,t,n){const r=e.messages.map(e=>e.id===t?ul(e,n):e);return{...e,messages:r}}var pl=n(void 0),hl=({children:e})=>{const[t,n]=p({isOpen:!1,activeView:"home",currentMode:"tell"}),r=u(()=>({setActiveView:e=>n(t=>({...t,activeView:e})),toggleWidget:()=>n(e=>({...e,isOpen:!e.isOpen})),closeWidget:()=>n(e=>({...e,isOpen:!1})),setMode:e=>n(t=>({...t,currentMode:e})),setError:e=>n(t=>({...t,error:e})),applyState:e=>n(t=>({...t,...e}))}),[]),o=u(()=>({uiState:t,uiActions:r}),[t,r]);/* @__PURE__ */
20
- return b(pl.Provider,{value:o,children:e})},fl=()=>{const e=s(pl);if(!e)throw new Error("useUIStateContext must be used within UIStateProvider");return e},ml=n(void 0),gl=({children:e,previewMode:t=!1})=>{const{uiState:n,uiActions:r}=fl(),[o,s]=p(()=>({messages:[],task:{phase:"idle"}})),c=d(o),l=Ac(n.currentMode),h=d(/* @__PURE__ */new Set),f=i(e=>{const t=c.current,n=e(t);n===t||n.messages===t.messages&&n.task===t.task||(c.current=n,s(n))},[]),m=i(e=>{f(t=>({...t,messages:[...t.messages,e]}))},[f]),g=i((e,t)=>{f(n=>({...n,messages:n.messages.map(n=>n.id===e?{...n,...t}:n)}))},[f]),y=i(e=>{f(t=>({...t,messages:t.messages.filter(t=>t.id!==e)}))},[f]),v=i(e=>{f(t=>({...t,messages:e}))},[f]),w=i(()=>{f(e=>({...e,messages:[]}))},[f]),x=i(()=>{f(e=>({...e,task:{phase:"idle"}}))},[f]),S=o.messages.filter(e=>e.isPlaceholder).map(e=>`${e.id}:${e.parts.length}`).join(" ");a(()=>{const e=S.split(" ").filter(Boolean).map(e=>e.split(":")[0]).filter(e=>void 0!==e).map(e=>setTimeout(()=>f(t=>function(e,t){const n=e.messages.find(e=>e.id===t);return n?.isPlaceholder&&"waiting-for-user"!==n.placeholderState?dl(e,t,"This is taking longer than expected. Please try again."):e}(t,e)),12e4));return()=>e.forEach(clearTimeout)},[S,f]);const k=i(async(e,n,r)=>{const o=n??l.current;if(t)return r||m(Jc(e,o)),void m(Zc("This is a preview. In production, I'll respond to your messages here."));if(!Be.getCredentialedConfig())return console.error("Config not loaded or incomplete"),void m(Zc("Configuration error: Missing API credentials. Please check your widget settings."));r||m(Jc(e,o));const i=(e=>Gc("temp","agent","",{mode:e,isPlaceholder:!0,placeholderState:"thinking"}))(o);f(e=>function(e,t){return{messages:[...e.messages,t],task:{phase:"idle"}}}(e,i));try{await async function(e,t,n){const r=await We.getOrCreateChatId(),o={type:`chat/${t}`,request_id:n,content:e};await fr.ready(r),await fr.send(o)}(e,o,i.id)}catch(s){console.error("Failed to send message:",s),f(e=>dl(e,i.id,el))}},[t,m,f]);a(()=>{if(t)return;const e=async e=>{const{toolCallId:t,tool:n,args:o,mode:i,explanation:s}=e,a=await Uc.executeTool(n,o,i,s),c=a.success?void 0:a.error;f(e=>function(e,t,n,r,o,i){return{...e,messages:nl(e.messages,"running"===e.task.phase,rl(e,o),t,n,r,i)}}(e,n,s,c?"failed":"completed",l.current,c)),c||"finish"!==n||f(e=>function(e,t){return sl(e,t,e=>({...e,taskStatus:"done",parts:e.parts.filter(e=>"progress"!==e.type)}))}(e,l.current)),await fr.send({type:"tool/response",tool_call_id:t,success:a.success,...a.success&&{data:JSON.stringify(a.data)},error:c}).catch(e=>{console.error("Failed to send tool response:",e),r.setError("Could not report that step back to the assistant — it may stop responding.")}),a.success&&a.afterResponseAttempt?.()},n={onMessage:t=>{if("tool/call"===t.type){const e=t.tool_call_id;if(h.current.has(e))return;h.current.add(e),h.current.size>1e3&&(h.current=new Set([...h.current].slice(-500)))}else"task/status"===t.type&&t.status in al?h.current.clear():"chat/error"===t.type&&Ae("[Widget] Chat error from server:",t.error);let n=[];f(e=>{const r=function(e,t,n){switch(t.type){case"tool/call":{if("stopped"===e.task.phase)return tl(e);const r="running"===e.task.phase?e.task:{phase:"running",mode:t.mode||n},o=t.explanation||"";return{state:{messages:nl(e.messages,!0,r.mode??n,t.browser_tool,o,"in_progress"),task:r},effects:[{type:"executeTool",toolCallId:t.tool_call_id,tool:t.browser_tool,args:t.args,mode:t.mode||n,explanation:o}]}}case"task/status":{if("running"===t.status)return tl(e);const r=t.status,o=e=>t.message?ll(e,t.message):e;return{state:sl(e,n,"has_question"===r?e=>({...o(e),placeholderState:"waiting-for-user"}):e=>({...o(e),taskStatus:al[r]})),effects:[]}}case"chat/delta":return{state:cl(e,t.request_id,t.text,!0),effects:[]};case"chat/response":return{state:cl(e,t.request_id,t.text,!1),effects:[]};case"chat/error":return{state:dl(e,t.request_id,el),effects:[]};default:return tl(e)}}(e,t,l.current);return n=r.effects,r.state});for(const o of n)e(o).catch(e=>{console.error("[Widget] Tool call failed:",e),r.setError("Something went wrong running that step. Please try again.")})},onError:e=>{r.setError(e.message),e instanceof hr&&f(t=>function(e,t){return{messages:e.messages.map(e=>e.isPlaceholder?ul(e,t):e),task:il(e.task)}}(t,e.message))}};return fr.addCallbacks(n),()=>{fr.removeCallbacks(n)}},[t,f,r]);const C=i(async()=>{f(e=>function(e,t){return{...sl(e,t,e=>({...e,taskStatus:"stopped"})),task:{phase:"stopped"}}}(e,l.current)),t||fr.send({type:"chat/stop"}).catch(e=>{console.error("Failed to stop task remotely:",e),r.setError("Could not stop the assistant — it may still be working.")})},[t,f,r]),E=u(()=>({addMessage:m,updateMessage:g,removeMessage:y,setMessages:v,clearMessages:w,messageDispatch:k}),[m,g,y,v,w,k]),I=u(()=>({resetTask:x,stopTask:C}),[x,C]),M=u(()=>({messages:o.messages,chatActions:E,taskState:o.task,taskActions:I}),[o.messages,E,o.task,I]);/* @__PURE__ */
20
+ return b(pl.Provider,{value:o,children:e})},fl=()=>{const e=s(pl);if(!e)throw new Error("useUIStateContext must be used within UIStateProvider");return e},ml=n(void 0),gl=({children:e,previewMode:t=!1})=>{const{uiState:n,uiActions:r}=fl(),[o,s]=p(()=>({messages:[],task:{phase:"idle"}})),c=d(o),l=Ac(n.currentMode),h=d(/* @__PURE__ */new Set),f=i(e=>{const t=c.current,n=e(t);n===t||n.messages===t.messages&&n.task===t.task||(c.current=n,s(n))},[]),m=i(e=>{f(t=>({...t,messages:[...t.messages,e]}))},[f]),g=i((e,t)=>{f(n=>({...n,messages:n.messages.map(n=>n.id===e?{...n,...t}:n)}))},[f]),y=i(e=>{f(t=>({...t,messages:t.messages.filter(t=>t.id!==e)}))},[f]),v=i(e=>{f(t=>({...t,messages:e}))},[f]),w=i(()=>{f(e=>({...e,messages:[]}))},[f]),x=i(()=>{f(e=>({...e,task:{phase:"idle"}}))},[f]),S=o.messages.filter(e=>e.isPlaceholder).map(e=>`${e.id}:${e.parts.length}`).join(" ");a(()=>{const e=S.split(" ").filter(Boolean).map(e=>e.split(":")[0]).filter(e=>void 0!==e).map(e=>setTimeout(()=>f(t=>function(e,t){const n=e.messages.find(e=>e.id===t);return n?.isPlaceholder&&"waiting-for-user"!==n.placeholderState?dl(e,t,"This is taking longer than expected. Please try again."):e}(t,e)),12e4));return()=>e.forEach(clearTimeout)},[S,f]);const k=i(async(e,n,r)=>{const o=n??l.current;if(t)return r||m(Jc(e,o)),void m(Zc("This is a preview. In production, I'll respond to your messages here."));if(!Be.getCredentialedConfig())return console.error("Config not loaded or incomplete"),void m(Zc("Configuration error: Missing API credentials. Please check your widget settings."));r||m(Jc(e,o));const i=(e=>Gc("temp","agent","",{mode:e,isPlaceholder:!0,placeholderState:"thinking"}))(o);f(e=>function(e,t){return{messages:[...e.messages,t],task:{phase:"idle"}}}(e,i));try{await async function(e,t,n){const r=await We.getOrCreateChatId(),o={type:`chat/${t}`,request_id:n,content:e};await fr.ready(r),await fr.send(o)}(e,o,i.id)}catch(s){console.error("Failed to send message:",s),f(e=>dl(e,i.id,el))}},[t,m,f]);a(()=>{if(t)return;const{handleMessage:e,handleError:n}=function(e){const{commit:t,currentModeRef:n,setError:r,processedToolCallIds:o}=e,i=async e=>{const{toolCallId:o,tool:i,args:s,mode:a,explanation:c}=e,l=await Uc.executeTool(i,s,a,c),u=l.success?void 0:l.error;t(e=>function(e,t,n,r,o,i){return{...e,messages:nl(e.messages,"running"===e.task.phase,rl(e,o),t,n,r,i)}}(e,i,c,u?"failed":"completed",n.current,u)),u||"finish"!==i||t(e=>sl(e,n.current,e=>({...e,taskStatus:"done",parts:e.parts.filter(e=>"progress"!==e.type)}))),await fr.send({type:"tool/response",tool_call_id:o,success:l.success,...l.success&&{data:JSON.stringify(l.data)},error:u}).catch(e=>{console.error("Failed to send tool response:",e),r("Could not report that step back to the assistant — it may stop responding.")}),l.success&&l.afterResponseAttempt?.()};return{handleMessage:e=>{if("tool/call"===e.type){const t=e.tool_call_id;if(o.current.has(t))return;o.current.add(t),o.current.size>1e3&&(o.current=new Set([...o.current].slice(-500)))}else"task/status"===e.type&&e.status in al?o.current.clear():"chat/error"===e.type&&Ae("[Widget] Chat error from server:",e.error);let s=[];t(t=>{const r=function(e,t,n){switch(t.type){case"tool/call":{if("stopped"===e.task.phase)return tl(e);const r="running"===e.task.phase?e.task:{phase:"running",mode:t.mode||n},o=t.explanation||"";return{state:{messages:nl(e.messages,!0,r.mode??n,t.browser_tool,o,"in_progress"),task:r},effects:[{type:"executeTool",toolCallId:t.tool_call_id,tool:t.browser_tool,args:t.args,mode:t.mode||n,explanation:o}]}}case"task/status":{if("running"===t.status)return tl(e);const r=t.status,o=e=>t.message?ll(e,t.message):e;return{state:sl(e,n,"has_question"===r?e=>({...o(e),placeholderState:"waiting-for-user"}):e=>({...o(e),taskStatus:al[r]})),effects:[]}}case"chat/delta":return{state:cl(e,t.request_id,t.text,!0),effects:[]};case"chat/response":return{state:cl(e,t.request_id,t.text,!1),effects:[]};case"chat/error":return{state:dl(e,t.request_id,el),effects:[]};default:return tl(e)}}(t,e,n.current);return s=r.effects,r.state});for(const t of s)i(t).catch(e=>{console.error("[Widget] Tool call failed:",e),r("Something went wrong running that step. Please try again.")})},handleError:e=>{r(e.message),e instanceof hr&&t(t=>{return n=t,r=e.message,{messages:n.messages.map(e=>e.isPlaceholder?ul(e,r):e),task:il(n.task)};var n,r})}}}({commit:f,currentModeRef:l,setError:r.setError,processedToolCallIds:h}),o={onMessage:e,onError:n};return fr.addCallbacks(o),()=>{fr.removeCallbacks(o)}},[t,f,r,l]);const C=i(async()=>{f(e=>function(e,t){return{...sl(e,t,e=>({...e,taskStatus:"stopped"})),task:{phase:"stopped"}}}(e,l.current)),t||fr.send({type:"chat/stop"}).catch(e=>{console.error("Failed to stop task remotely:",e),r.setError("Could not stop the assistant — it may still be working.")})},[t,f,r]),E=u(()=>({addMessage:m,updateMessage:g,removeMessage:y,setMessages:v,clearMessages:w,messageDispatch:k}),[m,g,y,v,w,k]),I=u(()=>({resetTask:x,stopTask:C}),[x,C]),M=u(()=>({messages:o.messages,chatActions:E,taskState:o.task,taskActions:I}),[o.messages,E,o.task,I]);/* @__PURE__ */
21
21
  return b(ml.Provider,{value:M,children:e})},yl=()=>{const e=s(ml);if(!e)throw new Error("useChatContext must be used within ChatProvider");return e},bl=n(null),vl=()=>{const{uiState:e}=fl(),{messages:t}=yl();return a(()=>{const{currentMode:n,isOpen:r}=e;var o;o={messages:t,currentMode:n,isOpen:r},Be.updateContext({...o,messages:o.messages.map(({videoStream:e,...t})=>{const n=t.timestamp.toISOString();if(!e)return{...t,timestamp:n,content:Re(t.parts)};const r="Screen sharing ended";return{...t,timestamp:n,content:r,isSystemMessage:!0,parts:[{type:"text",content:r}]}})})},[t,e]),null},wl=({children:e,previewMode:t})=>{const{uiActions:n}=fl(),{chatActions:r}=yl(),[o,i]=p(!1);return a(()=>{if(t)return;let e=!1;return(async()=>{const{messages:t,...o}=function(){const{chat_id:e,config:t,timestamp:n,messages:r,...o}=Be.getContext();return{...o,messages:r.map(({content:e,...t})=>{const n=[...t.parts],r=e.trim();return 0===n.length&&r&&n.push({type:"text",content:r}),{...t,timestamp:new Date(t.timestamp),parts:n}})}}();n.applyState(o),r.setMessages(t),i(!0);const s=await We.getOrCreateChatId();e||fr.connect(s)})().catch(t=>{e||(console.error("Widget initialization failed:",t),n.setError("Widget failed to initialise — please refresh the page."))}),()=>{e=!0}},[t,n,r]),/* @__PURE__ */v(y,{children:[e,o&&/* @__PURE__ */b(vl,{})]})},xl=({children:e,previewMode:t=!1})=>/* @__PURE__ */b(hl,{children:/* @__PURE__ */b(gl,{previewMode:t,children:/* @__PURE__ */b(wl,{previewMode:t,children:e})})}),Sl=/^#?([a-f\d]{3}|[a-f\d]{6})$/i,kl=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i;function Cl(e){const t=Sl.exec(e.trim())?.[1];if(t){const[e,n,r]=3===t.length?[t.charAt(0)+t.charAt(0),t.charAt(1)+t.charAt(1),t.charAt(2)+t.charAt(2)]:[t.slice(0,2),t.slice(2,4),t.slice(4,6)];return{r:parseInt(e??"",16),g:parseInt(n??"",16),b:parseInt(r??"",16)}}const n=kl.exec(e.trim());if(!n)return null;const r=Number(n[1]),o=Number(n[2]),i=Number(n[3]);return r>255||o>255||i>255?null:{r:r,g:o,b:i}}function El({r:e,g:t,b:n}){const r=e=>e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4);return.2126*r(e/255)+.7152*r(t/255)+.0722*r(n/255)}function Il(e,t){const n=Cl(e),r=Cl(t);if(!n||!r)return null;const o=El(n),i=El(r);return(Math.max(o,i)+.05)/(Math.min(o,i)+.05)}function Ml(e){return Cl(e)?(Il(e,"#000000")??0)>=(Il(e,"#ffffff")??0)?"#000000":"#ffffff":"#000000"}function Tl(e,t){const n=Cl(e);return n?`rgba(${n.r}, ${n.g}, ${n.b}, ${t})`:e}function Rl(e){return e.includes("gradient")?e:`linear-gradient(135deg, ${e} 0%, ${e} 100%)`}var Ol={widget_background_color:"#ffffff",widget_text_color:"#1f2937",widget_border_color:"#e5e7eb",widget_accent_color:"#3b82f6",widget_secondary_color:"#6b7280"},Al=n(null),_l=()=>{const e=s(Al);if(!e)throw new Error("useWidgetConfig must be used within WidgetRoot");return e},Dl=()=>{const{uiState:e,uiActions:t}=fl(),{messages:n,chatActions:r,taskState:o,taskActions:i}=yl();return{state:u(()=>({...e,messages:n,isTaskRunning:"running"===o.phase,isAwaitingReply:n.some(e=>e.isPlaceholder)}),[e,n,o]),actions:u(()=>({...t,...i,...r,clearChatHistory:()=>{r.clearMessages(),i.resetTask(),t.setError(void 0)}}),[t,i,r])}},Pl={bottom_right:{vertical:"bottom",horizontal:"right"},bottom_left:{vertical:"bottom",horizontal:"left"},top_right:{vertical:"top",horizontal:"right"},top_left:{vertical:"top",horizontal:"left"}},Nl=Object.keys(Pl),Ll=e=>Pl[e],Fl=e=>{const{vertical:t,horizontal:n}=Ll(e);return{[t]:"20px",[n]:"20px"}},zl={top:"bottom",bottom:"top",left:"right",right:"left"},$l=(e,t,n,r,o)=>{const{vertical:i,horizontal:s}=Ll(e);return{x:"left"===s?20:t-20-r,y:"top"===i?20:n-20-o}},Bl=class extends t.Component{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e,t){console.error(`${this.props.label} Error Boundary caught error:`,e,t)}render(){return this.state.hasError?this.props.fallback??null:this.props.children}},Wl="cubic-bezier(0.16, 1, 0.3, 1)",Ul=({onPositionCommit:e})=>{const{isPreviewMode:n=!1,widget_accent_color:r,widget_background_color:o,widget_position:s,widget_position_z_index:a}=_l(),{state:c,actions:u}=Dl(),h=c.isOpen,f=c.isTaskRunning,m=!!c.error,g=!h&&(c.isAwaitingReply||f),y=!h&&f,w=m?"error":"processing",x=d(null),{isDragging:S,pixelPositionStyle:k,onPointerDown:C,onPointerMove:E,onPointerUp:I,onPointerCancel:M,suppressUntilRef:T}=function({position:e,onPositionCommit:n,isPreviewMode:r=!1,wrapperRef:o}){const[s,a]=p(!1),[c,u]=p({w:56,h:56}),[,h]=p(0),f=d(null),m=d(null),g=d(null),y=d(0),b=d([]),v=d(0),w=()=>{null!==g.current&&window.cancelAnimationFrame(g.current),g.current=null};t.useEffect(()=>()=>{w(),f.current?.()},[]),t.useEffect(()=>{if(r)return;const e=()=>h(e=>e+1);return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[r]);const x=i(()=>{if(!o.current||"undefined"==typeof window)return;const e=o.current.getBoundingClientRect();u(t=>t.w===e.width&&t.h===e.height?t:{w:e.width,h:e.height})},[o]);l(()=>{x();const e="undefined"!=typeof window&&o.current?new ResizeObserver(x):null;return e&&o.current&&e.observe(o.current),()=>e?.disconnect()},[x,e,o]);const S="undefined"!=typeof window?window.innerWidth:0,k="undefined"!=typeof window?window.innerHeight:0,C=$l(e,S,k,c.w,c.h),E=!r&&S>0&&k>0?{left:C.x,top:C.y}:void 0,I=i(()=>{w(),o.current&&(o.current.style.transform="",o.current.style.willChange="",o.current.style.transition="",o.current.style.left="",o.current.style.top="")},[o]),M=i((e,t)=>{f.current?.();let r=!1;const i=()=>{r=!0,window.clearTimeout(c),t.removeEventListener("transitionend",l),f.current=null},s=()=>{r||(i(),t.style.transition="none",t.style.willChange="",t.style.left="",t.style.top="",n(e),a(!1),requestAnimationFrame(()=>{o.current&&(o.current.style.transition="")}))},c=window.setTimeout(s,650),l=e=>{e.target===t&&"left"===e.propertyName&&s()};t.addEventListener("transitionend",l),f.current=i},[n,o]),T=i((t,r,i)=>{if(!o.current||!E)return I(),n(t),void a(!1);w();const s=o.current,l=$l(e,S,k,c.w,c.h),u=$l(t,S,k,c.w,c.h);s.style.transition="none",s.style.transform="none",s.style.willChange="left, top",s.style.left=`${l.x+r}px`,s.style.top=`${l.y+i}px`,requestAnimationFrame(()=>{s.style.transition=`left 600ms ${Wl}, top 600ms ${Wl}`,s.style.left=`${u.x}px`,s.style.top=`${u.y}px`}),M(t,s)},[M,n,E,e,I,S,k,c.w,c.h,o]),R=e=>{I(),m.current=null,a(!1),e.currentTarget.releasePointerCapture(e.pointerId)};return{isDragging:s,pixelPositionStyle:E,onPointerDown:e=>{m.current={pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,dragging:!1,lastX:0,lastY:0},e.currentTarget.setPointerCapture(e.pointerId)},onPointerMove:e=>{const t=m.current;if(t?.pointerId!==e.pointerId)return;const n=e.clientX-t.startX,r=e.clientY-t.startY;if(!t.dragging&&Math.hypot(n,r)>5&&(t.dragging=!0,a(!0),b.current=[],v.current=0,o.current&&(o.current.style.willChange="transform",o.current.style.transition="none")),!t.dragging)return;t.lastX=n,t.lastY=r;const i=Date.now();i-v.current>=10&&(v.current=i,b.current=[...b.current.slice(-5),{x:e.clientX,y:e.clientY,t:i}]),null===g.current&&(g.current=window.requestAnimationFrame(()=>{g.current=null;const e=m.current,t=o.current;t&&e&&(t.style.transform=`translate3d(${e.lastX}px, ${e.lastY}px, 0)`)}))},onPointerUp:t=>{const n=m.current;if(n?.pointerId===t.pointerId){if(n.dragging){const r=function(e,t=.999){if(e.length<2)return{x:0,y:0};const n=e[0],r=e[e.length-1];if(!n||!r)return{x:0,y:0};const o=r.t-n.t;if(o<=0)return{x:0,y:0};const i=e=>e/o*t/(1-t);return{x:i(r.x-n.x),y:i(r.y-n.y)}}(b.current),i={dx:n.lastX+r.x,dy:n.lastY+r.y},s=o.current?.getBoundingClientRect(),a=s?((e,t,n,r,o,i)=>{const s=$l(t,n,r,o,i),a=s.x+e.dx,c=s.y+e.dy;let l=t,u=1/0;for(const d of Nl){const e=$l(d,n,r,o,i),t=Math.hypot(a-e.x,c-e.y);t<u&&(u=t,l=d)}return l})(i,e,window.innerWidth,window.innerHeight,s.width,s.height):e;return T(a,n.lastX,n.lastY),y.current=Date.now()+600,m.current=null,void t.currentTarget.releasePointerCapture(t.pointerId)}R(t)}},onPointerCancel:e=>{m.current?.pointerId===e.pointerId&&R(e)},suppressUntilRef:y}}({position:s,onPositionCommit:e,isPreviewMode:n,wrapperRef:x});/* @__PURE__ */
22
22
  return b(yc,{ref:x,className:"mtx-fab-anchor","data-animated":S?"false":"true","data-preview":n?"true":"false",style:{zIndex:a,pointerEvents:h?"none":"auto",...S?k:Fl(s)},children:/* @__PURE__ */v(yc,{className:"mtx-fab","data-open":h?"true":"false",children:[g&&/* @__PURE__ */b(yc,{className:"mtx-fab-glow","data-tone":w,"aria-hidden":!0}),y&&!S&&/* @__PURE__ */b(pc,{variant:"secondary",size:"sm",className:"mtx-fab-stop","data-side":s.includes("left")?"left":"right",onClick:e=>{e.preventDefault(),e.stopPropagation(),u.stopTask()},children:"Stop"}),
23
23
  /* @__PURE__ */b(pc,{variant:"bare",onClick:()=>{Date.now()<T.current||u.toggleWidget()},onDragStart:e=>e.preventDefault(),onPointerDown:C,onPointerMove:E,onPointerUp:I,onPointerCancel:M,className:"mtx-fab-trigger",style:{touchAction:"none",cursor:S?"grabbing":"grab",userSelect:"none",WebkitUserSelect:"none"},"aria-label":h?"Close":"Open","aria-live":"polite",children:/* @__PURE__ */b(bc,{className:"mtx-fab-center",children:/* @__PURE__ */v(yc,{className:"mtx-fab-badge",style:{borderRadius:"12px",backgroundColor:h?o:r,boxShadow:kr.fab},children:[g&&/* @__PURE__ */b("svg",{className:"mtx-fab-ring","data-tone":w,viewBox:"0 0 54 54",fill:"none","aria-hidden":!0,children:/* @__PURE__ */b("rect",{x:"1.25",y:"1.25",width:"51.5",height:"51.5",rx:13,ry:13})}),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marketrix.ai/widget",
3
- "version": "4.0.125",
3
+ "version": "4.0.127",
4
4
  "type": "module",
5
5
  "packageManager": "bun@1.4.2",
6
6
  "sideEffects": false,