@yassirbenmoussa/aicommerce-sdk 1.6.0 → 1.8.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/README.md CHANGED
@@ -30,6 +30,7 @@ import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';
30
30
  // Initialize the client
31
31
  const client = new AICommerce({
32
32
  apiKey: 'your-api-key',
33
+ storeId: 'your-store-id',
33
34
  });
34
35
 
35
36
  // Send a message and get product recommendations
@@ -46,6 +47,7 @@ const { AICommerce } = require('@yassirbenmoussa/aicommerce-sdk');
46
47
 
47
48
  const client = new AICommerce({
48
49
  apiKey: 'your-api-key',
50
+ storeId: 'your-store-id',
49
51
  });
50
52
 
51
53
  client.chat('I need a laptop').then(response => {
@@ -59,7 +61,8 @@ client.chat('I need a laptop').then(response => {
59
61
  <script src="https://cdn.aicommerce.dev/sdk/ai-commerce.min.js"></script>
60
62
  <script>
61
63
  const client = new AICommerceSDK.AICommerce({
62
- apiKey: 'your-api-key'
64
+ apiKey: 'your-api-key',
65
+ storeId: 'your-store-id'
63
66
  });
64
67
 
65
68
  client.chat('I need a laptop').then(response => {
@@ -77,6 +80,7 @@ Create a new AI Commerce client.
77
80
  | Option | Type | Required | Description |
78
81
  |--------|------|----------|-------------|
79
82
  | `apiKey` | `string` | Yes | Your API key from the dashboard |
83
+ | `storeId` | `string` | Yes | Your Store ID from the dashboard |
80
84
  | `baseUrl` | `string` | No | API base URL (defaults to auto-detect) |
81
85
  | `timeout` | `number` | No | Request timeout in ms (default: 30000) |
82
86
 
@@ -1,5 +1,5 @@
1
1
  var AICommerceSDK=(function(exports){'use strict';/*! AI Commerce SDK v1.0.0 | MIT License | https://aicommerce.dev */
2
- var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var le=Object.prototype.hasOwnProperty;var B=(t,e)=>()=>(t&&(e=t(t=0)),e);var Y=(t,e)=>{for(var r in e)O(t,r,{get:e[r],enumerable:true});},me=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let u of de(e))!le.call(t,u)&&u!==r&&O(t,u,{get:()=>e[u],enumerable:!(a=ce(e,u))||a.enumerable});return t};var W=t=>me(O({},"__esModule",{value:true}),t);var z={};Y(z,{AICommerce:()=>exports.AICommerce,AICommerceError:()=>exports.AICommerceError});exports.AICommerce=void 0;exports.AICommerceError=void 0;var $=B(()=>{exports.AICommerce=class t{constructor(e){this.sessionToken=null;this.products={create:async e=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify(e)}),batchUpsert:async e=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify({products:e})}),list:async e=>{let r=new URLSearchParams;e?.page&&r.set("page",String(e.page)),e?.perPage&&r.set("perPage",String(e.perPage)),e?.search&&r.set("search",e.search),e?.categoryId&&r.set("categoryId",e.categoryId),e?.isActive!==void 0&&r.set("isActive",String(e.isActive));let a=r.toString();return this.request(`/api/v1/products${a?`?${a}`:""}`)},get:async e=>this.request(`/api/v1/products/${e}`),update:async(e,r)=>this.request(`/api/v1/products/${e}`,{method:"PUT",body:JSON.stringify(r)}),delete:async e=>this.request(`/api/v1/products/${e}`,{method:"DELETE"})};if(!e.apiKey)throw new Error("AICommerce: apiKey is required");this.apiKey=e.apiKey,this.storeId=e.storeId,this.baseUrl=this.normalizeUrl(e.baseUrl||this.detectBaseUrl()),this.timeout=e.timeout||3e4;}detectBaseUrl(){if(typeof window<"u"){let e=document.querySelector("script[data-aicommerce-url]");if(e)return e.getAttribute("data-aicommerce-url")||"https://api.aicommerce.dev"}return "https://api.aicommerce.dev"}normalizeUrl(e){return e.replace(/\/$/,"")}async request(e,r={}){let a=`${this.baseUrl}${e}`,u=new AbortController,s=setTimeout(()=>u.abort(),this.timeout);try{let m=await fetch(a,{...r,signal:u.signal,headers:{"Content-Type":"application/json","x-api-key":this.apiKey,...this.storeId&&{"x-store-id":this.storeId},...this.sessionToken&&{"X-Session-Token":this.sessionToken},...r.headers}});if(clearTimeout(s),!m.ok){let T=await m.json().catch(()=>({})),f={code:T.code||"UNKNOWN_ERROR",message:T.message||T.error||`HTTP ${m.status}`,status:m.status};throw new exports.AICommerceError(f.message,f.code,f.status)}return m.json()}catch(m){throw clearTimeout(s),m instanceof exports.AICommerceError?m:m instanceof Error&&m.name==="AbortError"?new exports.AICommerceError("Request timeout","TIMEOUT",408):new exports.AICommerceError(m instanceof Error?m.message:"Unknown error","NETWORK_ERROR",0)}}async chat(e,r){let a=typeof e=="string"?{message:e,context:r,sessionToken:this.sessionToken||void 0}:{...e,sessionToken:e.sessionToken||this.sessionToken||void 0},u=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(a)});return u.sessionToken&&(this.sessionToken=u.sessionToken),u}async chatWithAudio(e,r){let a=await e.arrayBuffer(),s={audioBase64:btoa(new Uint8Array(a).reduce((T,f)=>T+String.fromCharCode(f),"")),audioMimeType:e.type||"audio/webm",context:r,sessionToken:this.sessionToken||void 0},m=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(s)});return m.sessionToken&&(this.sessionToken=m.sessionToken),m}async createSession(){let e=await this.request("/api/v1/chat/session",{method:"POST"});return this.sessionToken=e.session.token,e.session}clearSession(){this.sessionToken=null;}getSessionToken(){return this.sessionToken}setSessionToken(e){this.sessionToken=e;}async upload(e,r){let a=new FormData;a.append("file",e),r?.folder&&a.append("folder",r.folder),r?.productId&&a.append("productId",r.productId),r?.isPrimary&&a.append("isPrimary","true");let u=`${this.baseUrl}/api/v1/upload`,s=await fetch(u,{method:"POST",headers:{"X-API-Key":this.apiKey},body:a});if(!s.ok){let m=await s.json().catch(()=>({}));throw new exports.AICommerceError(m.message||m.error||`HTTP ${s.status}`,m.code||"UPLOAD_ERROR",s.status)}return s.json()}static async quickChat(e){return new t({apiKey:e.apiKey,baseUrl:e.baseUrl}).chat(e.message,e.context)}},exports.AICommerceError=class t extends Error{constructor(e,r,a){super(e),this.name="AICommerceError",this.code=r,this.status=a,Object.setPrototypeOf(this,t.prototype);}};});function ue(t){let e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:{r:99,g:102,b:241}}function D(t){let e=t.primaryColor,r=ue(e),a=t.position==="bottom-left";return `
2
+ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var me=Object.prototype.hasOwnProperty;var B=(t,e)=>()=>(t&&(e=t(t=0)),e);var Y=(t,e)=>{for(var r in e)O(t,r,{get:e[r],enumerable:true});},le=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let g of de(e))!me.call(t,g)&&g!==r&&O(t,g,{get:()=>e[g],enumerable:!(s=ce(e,g))||s.enumerable});return t};var W=t=>le(O({},"__esModule",{value:true}),t);var D={};Y(D,{AICommerce:()=>exports.AICommerce,AICommerceError:()=>exports.AICommerceError});exports.AICommerce=void 0;exports.AICommerceError=void 0;var L=B(()=>{exports.AICommerce=class t{constructor(e){this.sessionToken=null;this.products={create:async e=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify(e)}),batchUpsert:async e=>this.request("/api/v1/products",{method:"POST",body:JSON.stringify({products:e})}),list:async e=>{let r=new URLSearchParams;e?.page&&r.set("page",String(e.page)),e?.perPage&&r.set("perPage",String(e.perPage)),e?.search&&r.set("search",e.search),e?.categoryId&&r.set("categoryId",e.categoryId),e?.isActive!==void 0&&r.set("isActive",String(e.isActive));let s=r.toString();return this.request(`/api/v1/products${s?`?${s}`:""}`)},get:async e=>this.request(`/api/v1/products/${e}`),update:async(e,r)=>this.request(`/api/v1/products/${e}`,{method:"PUT",body:JSON.stringify(r)}),delete:async e=>this.request(`/api/v1/products/${e}`,{method:"DELETE"})};if(!e.apiKey)throw new Error("AICommerce: apiKey is required");this.apiKey=e.apiKey,this.storeId=e.storeId,this.baseUrl=this.normalizeUrl(e.baseUrl||this.detectBaseUrl()),this.timeout=e.timeout||3e4;}detectBaseUrl(){if(typeof window<"u"){let e=document.querySelector("script[data-aicommerce-url]");if(e)return e.getAttribute("data-aicommerce-url")||"https://api.aicommerce.dev"}return "https://api.aicommerce.dev"}normalizeUrl(e){return e.replace(/\/$/,"")}async request(e,r={}){let s=`${this.baseUrl}${e}`,g=new AbortController,a=setTimeout(()=>g.abort(),this.timeout);try{let p=await fetch(s,{...r,signal:g.signal,headers:{"Content-Type":"application/json","x-api-key":this.apiKey,...this.storeId&&{"x-store-id":this.storeId},...this.sessionToken&&{"X-Session-Token":this.sessionToken},...r.headers}});if(clearTimeout(a),!p.ok){let E=await p.json().catch(()=>({})),b={code:E.code||"UNKNOWN_ERROR",message:E.message||E.error||`HTTP ${p.status}`,status:p.status};throw new exports.AICommerceError(b.message,b.code,b.status)}return p.json()}catch(p){throw clearTimeout(a),p instanceof exports.AICommerceError?p:p instanceof Error&&p.name==="AbortError"?new exports.AICommerceError("Request timeout","TIMEOUT",408):new exports.AICommerceError(p instanceof Error?p.message:"Unknown error","NETWORK_ERROR",0)}}async chat(e,r){let s=typeof e=="string"?{message:e,context:r,sessionToken:this.sessionToken||void 0}:{...e,sessionToken:e.sessionToken||this.sessionToken||void 0},g=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(s)});return g.sessionToken&&(this.sessionToken=g.sessionToken),g}async chatWithAudio(e,r){let s=await e.arrayBuffer(),a={audioBase64:btoa(new Uint8Array(s).reduce((E,b)=>E+String.fromCharCode(b),"")),audioMimeType:e.type||"audio/webm",context:r,sessionToken:this.sessionToken||void 0},p=await this.request("/api/v1/chat",{method:"POST",body:JSON.stringify(a)});return p.sessionToken&&(this.sessionToken=p.sessionToken),p}async createSession(){let e=await this.request("/api/v1/chat/session",{method:"POST"});return this.sessionToken=e.session.token,e.session}clearSession(){this.sessionToken=null;}getSessionToken(){return this.sessionToken}setSessionToken(e){this.sessionToken=e;}async upload(e,r){let s=new FormData;s.append("file",e),r?.folder&&s.append("folder",r.folder),r?.productId&&s.append("productId",r.productId),r?.isPrimary&&s.append("isPrimary","true");let g=`${this.baseUrl}/api/v1/upload`,a=await fetch(g,{method:"POST",headers:{"X-API-Key":this.apiKey},body:s});if(!a.ok){let p=await a.json().catch(()=>({}));throw new exports.AICommerceError(p.message||p.error||`HTTP ${a.status}`,p.code||"UPLOAD_ERROR",a.status)}return a.json()}static async quickChat(e){return new t({apiKey:e.apiKey,baseUrl:e.baseUrl}).chat(e.message,e.context)}},exports.AICommerceError=class t extends Error{constructor(e,r,s){super(e),this.name="AICommerceError",this.code=r,this.status=s,Object.setPrototypeOf(this,t.prototype);}};});function ue(t){let e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:{r:99,g:102,b:241}}function H(t){let e=t.primaryColor,r=ue(e),s=t.position==="bottom-left";return `
3
3
  /* AI Commerce Widget Styles */
4
4
  #aicommerce-widget {
5
5
  --aic-primary: ${e};
@@ -20,7 +20,7 @@ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object
20
20
  line-height: 1.5;
21
21
  position: fixed;
22
22
  bottom: 20px;
23
- ${a?"left: 20px;":"right: 20px;"}
23
+ ${s?"left: 20px;":"right: 20px;"}
24
24
  z-index: var(--aic-z-index);
25
25
  }
26
26
 
@@ -74,7 +74,7 @@ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object
74
74
  .aicommerce-chat {
75
75
  position: absolute;
76
76
  bottom: 0;
77
- ${a?"left: 0;":"right: 0;"}
77
+ ${s?"left: 0;":"right: 0;"}
78
78
  width: 380px;
79
79
  max-width: calc(100vw - 40px);
80
80
  height: 600px;
@@ -86,7 +86,7 @@ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object
86
86
  flex-direction: column;
87
87
  overflow: hidden;
88
88
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
89
- transform-origin: bottom ${a?"left":"right"};
89
+ transform-origin: bottom ${s?"left":"right"};
90
90
  }
91
91
 
92
92
  .aicommerce-chat.aicommerce-closed {
@@ -515,7 +515,7 @@ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object
515
515
  @media (max-width: 420px) {
516
516
  #aicommerce-widget {
517
517
  bottom: 16px;
518
- ${a?"left: 16px;":"right: 16px;"}
518
+ ${s?"left: 16px;":"right: 16px;"}
519
519
  }
520
520
 
521
521
  .aicommerce-chat {
@@ -547,46 +547,102 @@ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object
547
547
  .aicommerce-messages::-webkit-scrollbar-thumb:hover {
548
548
  background: var(--aic-text-secondary);
549
549
  }
550
- `}function J(t){let e=document.createElement("style");e.id="aicommerce-widget-styles",e.textContent=t;let r=document.getElementById("aicommerce-widget-styles");return r&&r.remove(),document.head.appendChild(e),e}var V=B(()=>{});var X={};Y(X,{AICommerceWidget:()=>exports.AICommerceWidget,createWidget:()=>j});function j(t){if(!t.apiKey)throw new Error("AICommerceWidget: apiKey is required");let e=new exports.AICommerce({apiKey:t.apiKey,storeId:t.storeId,baseUrl:t.baseUrl}),r={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},a=null,u=[],s=null,f=null,p;async function _(){try{let o=t.baseUrl||K(),i=await fetch(`${o}/api/v1/store`,{headers:{"x-api-key":t.apiKey}});return i.ok?(await i.json()).store:null}catch(o){return console.error("Failed to fetch store config:",o),null}}function K(){if(typeof window<"u"){let o=document.querySelector("script[data-aicommerce-url]");if(o)return o.getAttribute("data-aicommerce-url")||""}return "https://api.aicommerce.dev"}async function G(){r.storeConfig=await _(),p={apiKey:t.apiKey,storeId:t.storeId,baseUrl:t.baseUrl||K(),position:t.position||"bottom-right",theme:t.theme||"auto",primaryColor:t.primaryColor||r.storeConfig?.primaryColor||"#6366f1",welcomeMessage:t.welcomeMessage||r.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:t.botName||r.storeConfig?.chatBotName||"Shopping Assistant",zIndex:t.zIndex||9999,buttonText:t.buttonText||"\u{1F4AC}",hideLauncher:t.hideLauncher||false,onOpen:t.onOpen,onClose:t.onClose,onProductClick:t.onProductClick,onMessage:t.onMessage};let o=D(p);f=J(o),s=document.createElement("div"),s.id="aicommerce-widget",s.className=`aicommerce-widget aicommerce-${p.position} aicommerce-theme-${p.theme}`,document.body.appendChild(s),b(),r.messages.push({role:"assistant",content:p.welcomeMessage}),r.isLoading=false,b();}function b(){if(!s)return;let o=`
551
- ${p.hideLauncher?"":`
550
+
551
+ /* ============================================
552
+ Embedded Mode Styles
553
+ ============================================ */
554
+
555
+ /* Embedded container - position relative, inline flow */
556
+ #aicommerce-widget.aicommerce-embedded {
557
+ position: relative;
558
+ bottom: auto;
559
+ left: auto;
560
+ right: auto;
561
+ width: 100%;
562
+ height: var(--aic-height, 500px);
563
+ }
564
+
565
+ /* Embedded mode: hide launcher button */
566
+ .aicommerce-embedded .aicommerce-launcher {
567
+ display: none !important;
568
+ }
569
+
570
+ /* Embedded mode: chat is always visible and fills container */
571
+ .aicommerce-embedded .aicommerce-chat {
572
+ position: relative;
573
+ width: 100%;
574
+ height: 100%;
575
+ max-width: 100%;
576
+ max-height: 100%;
577
+ border-radius: var(--aic-radius);
578
+ transform: none !important;
579
+ opacity: 1 !important;
580
+ pointer-events: auto !important;
581
+ }
582
+
583
+ /* Embedded mode: no open/close animations */
584
+ .aicommerce-embedded .aicommerce-chat.aicommerce-closed {
585
+ opacity: 1 !important;
586
+ transform: none !important;
587
+ pointer-events: auto !important;
588
+ }
589
+
590
+ /* Embedded mode: messages area adjusts to container */
591
+ .aicommerce-embedded .aicommerce-messages {
592
+ flex: 1;
593
+ min-height: 0;
594
+ }
595
+
596
+ /* Embedded mode responsive */
597
+ @media (max-width: 420px) {
598
+ #aicommerce-widget.aicommerce-embedded {
599
+ height: var(--aic-height, 400px);
600
+ }
601
+
602
+ .aicommerce-embedded .aicommerce-chat {
603
+ border-radius: 12px;
604
+ }
605
+ }
606
+ `}function J(t){let e=document.createElement("style");e.id="aicommerce-widget-styles",e.textContent=t;let r=document.getElementById("aicommerce-widget-styles");return r&&r.remove(),document.head.appendChild(e),e}var V=B(()=>{});var X={};Y(X,{AICommerceWidget:()=>exports.AICommerceWidget,createWidget:()=>j});function j(t){if(!t.apiKey)throw new Error("AICommerceWidget: apiKey is required");let e=new exports.AICommerce({apiKey:t.apiKey,storeId:t.storeId,baseUrl:t.baseUrl}),r={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},s=null,g=[],a=null,b=null,l;async function _(){try{let o=t.baseUrl||N(),i=await fetch(`${o}/api/v1/store`,{headers:{"x-api-key":t.apiKey}});return i.ok?(await i.json()).store:null}catch(o){return console.error("Failed to fetch store config:",o),null}}function N(){if(typeof window<"u"){let o=document.querySelector("script[data-aicommerce-url]");if(o)return o.getAttribute("data-aicommerce-url")||""}return "https://api.aicommerce.dev"}async function G(){r.storeConfig=await _();let o=t.displayMode||"widget",i=o==="embedded";l={apiKey:t.apiKey,storeId:t.storeId,baseUrl:t.baseUrl||N(),displayMode:o,container:t.container,height:t.height||"500px",position:t.position||"bottom-right",theme:t.theme||"auto",primaryColor:t.primaryColor||r.storeConfig?.primaryColor||"#6366f1",welcomeMessage:t.welcomeMessage||r.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:t.botName||r.storeConfig?.chatBotName||"Shopping Assistant",zIndex:t.zIndex||9999,buttonText:t.buttonText||"\u{1F4AC}",hideLauncher:t.hideLauncher||false,onOpen:t.onOpen,onClose:t.onClose,onProductClick:t.onProductClick,onMessage:t.onMessage};let c=H(l);if(b=J(c),i){let d=null;if(typeof t.container=="string"?d=document.querySelector(t.container):t.container instanceof HTMLElement&&(d=t.container),!d){console.error("[AI Commerce] Embedded mode requires a valid container element or selector");return}a=document.createElement("div"),a.id="aicommerce-widget",a.className=`aicommerce-widget aicommerce-embedded aicommerce-theme-${l.theme}`,a.style.setProperty("--aic-height",l.height),d.appendChild(a),r.isOpen=true;}else a=document.createElement("div"),a.id="aicommerce-widget",a.className=`aicommerce-widget aicommerce-${l.position} aicommerce-theme-${l.theme}`,document.body.appendChild(a);y(),r.messages.push({role:"assistant",content:l.welcomeMessage}),r.isLoading=false,y();}function y(){if(!a)return;let o=l.displayMode==="embedded",i=`
607
+ ${!o&&!l.hideLauncher?`
552
608
  <button class="aicommerce-launcher ${r.isOpen?"aicommerce-hidden":""}" aria-label="Open chat">
553
- <span class="aicommerce-launcher-icon">${p.buttonText}</span>
609
+ <span class="aicommerce-launcher-icon">${l.buttonText}</span>
554
610
  </button>
555
- `}
611
+ `:""}
556
612
 
557
613
  <div class="aicommerce-chat ${r.isOpen?"aicommerce-open":"aicommerce-closed"}">
558
614
  <div class="aicommerce-header">
559
615
  <div class="aicommerce-header-info">
560
616
  <div class="aicommerce-avatar">
561
- ${r.storeConfig?.logo?`<img src="${r.storeConfig.logo}" alt="${p.botName}" />`:"<span>\u{1F916}</span>"}
617
+ ${r.storeConfig?.logo?`<img src="${r.storeConfig.logo}" alt="${l.botName}" />`:"<span>\u{1F916}</span>"}
562
618
  </div>
563
619
  <div class="aicommerce-header-text">
564
- <span class="aicommerce-bot-name">${p.botName}</span>
620
+ <span class="aicommerce-bot-name">${l.botName}</span>
565
621
  <span class="aicommerce-status">Online</span>
566
622
  </div>
567
623
  </div>
568
- <button class="aicommerce-close" aria-label="Close chat">\u2715</button>
624
+ ${o?"":'<button class="aicommerce-close" aria-label="Close chat">\u2715</button>'}
569
625
  </div>
570
626
 
571
627
  <div class="aicommerce-messages">
572
- ${r.messages.map((n,y)=>{let l=te(n.content),P=n.role==="user";return `
573
- <div class="aicommerce-message aicommerce-${n.role}">
574
- <div class="aicommerce-message-content ${l?"aicommerce-rtl":"aicommerce-ltr"}">
575
- ${n.audioUrl?Q(n,y,P):R(n.content)}
628
+ ${r.messages.map((d,u)=>{let P=te(d.content),T=d.role==="user";return `
629
+ <div class="aicommerce-message aicommerce-${d.role}">
630
+ <div class="aicommerce-message-content ${P?"aicommerce-rtl":"aicommerce-ltr"}">
631
+ ${d.audioUrl?Q(d,u,T):R(d.content)}
576
632
  </div>
577
- ${n.products&&n.products.length>0?`
633
+ ${d.products&&d.products.length>0?`
578
634
  <div class="aicommerce-products">
579
- ${n.products.map(g=>`
580
- <div class="aicommerce-product-card" data-product-id="${g.id}">
581
- ${g.image||g.imageUrl?`
582
- <img src="${g.image||g.imageUrl}" alt="${R(g.name)}" class="aicommerce-product-image" />
635
+ ${d.products.map(h=>`
636
+ <div class="aicommerce-product-card" data-product-id="${h.id}">
637
+ ${h.image||h.imageUrl?`
638
+ <img src="${h.image||h.imageUrl}" alt="${R(h.name)}" class="aicommerce-product-image" />
583
639
  `:`
584
640
  <div class="aicommerce-product-placeholder">\u{1F4E6}</div>
585
641
  `}
586
642
  <div class="aicommerce-product-info">
587
- <span class="aicommerce-product-name" title="${R(g.name)}">${R(g.name)}</span>
588
- ${g.description?`<p class="aicommerce-product-desc">${R(g.description)}</p>`:""}
589
- <span class="aicommerce-product-price">${ne(g.price,g.currency)}</span>
643
+ <span class="aicommerce-product-name" title="${R(h.name)}">${R(h.name)}</span>
644
+ ${h.description?`<p class="aicommerce-product-desc">${R(h.description)}</p>`:""}
645
+ <span class="aicommerce-product-price">${ne(h.price,h.currency)}</span>
590
646
  </div>
591
647
  </div>
592
648
  `).join("")}
@@ -631,23 +687,23 @@ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object
631
687
  </button>
632
688
  </div>
633
689
  </div>
634
- `;s.innerHTML=o,Z();let i=s.querySelector(".aicommerce-messages");i&&(i.scrollTop=i.scrollHeight);}function Q(o,i,n){return `
690
+ `;a.innerHTML=i,Z();let c=a.querySelector(".aicommerce-messages");c&&(c.scrollTop=c.scrollHeight);}function Q(o,i,c){return `
635
691
  <div class="aicommerce-audio-player" data-message-index="${i}">
636
692
  <button class="aicommerce-audio-btn">
637
693
  <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
638
694
  </button>
639
695
  <div class="aicommerce-audio-waveform">
640
696
  <div class="aicommerce-waveform-bars">
641
- ${(o.waveformBars||Array(40).fill(10)).map(y=>`
642
- <div class="aicommerce-waveform-bar" style="height: ${y}%; background-color: ${n?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)"}"></div>
697
+ ${(o.waveformBars||Array(40).fill(10)).map(d=>`
698
+ <div class="aicommerce-waveform-bar" style="height: ${d}%; background-color: ${c?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)"}"></div>
643
699
  `).join("")}
644
700
  </div>
645
701
  <div class="aicommerce-audio-time">
646
702
  <span class="aicommerce-current-time">0:00</span>
647
- <span>${N(o.audioDuration||0)}</span>
703
+ <span>${K(o.audioDuration||0)}</span>
648
704
  </div>
649
705
  </div>
650
706
  <audio src="${o.audioUrl}" preload="metadata"></audio>
651
707
  </div>
652
- `}function Z(){if(!s)return;let o=s.querySelector(".aicommerce-launcher");o&&o.addEventListener("click",()=>L());let i=s.querySelector(".aicommerce-close");i&&i.addEventListener("click",()=>M());let n=s.querySelector(".aicommerce-input"),y=s.querySelector(".aicommerce-send");n&&n.addEventListener("keypress",c=>{c.key==="Enter"&&n.value.trim()&&(A(n.value.trim()),n.value="");}),y&&n&&y.addEventListener("click",()=>{n.value.trim()&&(A(n.value.trim()),n.value="");});let l=s.querySelector(".aicommerce-mic");l&&l.addEventListener("click",()=>ee()),s.querySelectorAll(".aicommerce-product-card").forEach(c=>{c.addEventListener("click",()=>{let d=c.getAttribute("data-product-id"),h=r.messages.flatMap(x=>x.products||[]).find(x=>x.id===d);h&&(p.onProductClick?p.onProductClick(h):h.url&&window.open(h.url,"_blank","noopener,noreferrer"));});}),s.querySelectorAll(".aicommerce-products").forEach(c=>{let d=false,h=0,x=0;c.addEventListener("mousedown",k=>{d=true,c.style.cursor="grabbing",h=k.pageX-c.offsetLeft,x=c.scrollLeft;}),c.addEventListener("mouseleave",()=>{d=false,c.style.cursor="grab";}),c.addEventListener("mouseup",()=>{d=false,c.style.cursor="grab";}),c.addEventListener("mousemove",k=>{if(!d)return;k.preventDefault();let v=(k.pageX-c.offsetLeft-h)*2;c.scrollLeft=x-v;});}),s.querySelectorAll(".aicommerce-audio-player").forEach(c=>{let d=c.querySelector("audio"),h=c.querySelector(".aicommerce-audio-btn"),x=c.querySelectorAll(".aicommerce-waveform-bar"),k=c.querySelector(".aicommerce-current-time");if(!d||!h)return;h.addEventListener("click",()=>{!d.paused?(d.pause(),h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'):(s?.querySelectorAll("audio").forEach(w=>{if(w!==d&&!w.paused){w.pause();let E=w.closest(".aicommerce-audio-player")?.querySelector(".aicommerce-audio-btn");E&&(E.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');}}),d.play(),h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');}),d.addEventListener("timeupdate",()=>{if(k&&(k.textContent=N(d.currentTime)),d.duration){let v=d.currentTime/d.duration*100;x.forEach((w,q)=>{q/x.length*100<=v?w.style.backgroundColor=c.closest(".aicommerce-user")?"rgba(255,255,255,1)":"var(--aic-primary)":w.style.backgroundColor=c.closest(".aicommerce-user")?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)";});}}),d.addEventListener("ended",()=>{h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';});let S=c.querySelector(".aicommerce-waveform-bars");S&&S.addEventListener("click",v=>{let w=S.getBoundingClientRect(),E=(v.clientX-w.left)/w.width;d.duration&&(d.currentTime=E*d.duration);});});}async function ee(){if(r.isRecording)a&&a.state!=="inactive"&&a.stop();else try{let o=await navigator.mediaDevices.getUserMedia({audio:!0});u=[],a=new MediaRecorder(o,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),a.ondataavailable=i=>{i.data.size>0&&u.push(i.data);},a.onstop=async()=>{if(o.getTracks().forEach(i=>i.stop()),u.length>0){let i=new Blob(u,{type:a?.mimeType||"audio/webm"});await re(i);}r.isRecording=!1,b();},a.start(),r.isRecording=!0,b();}catch(o){console.error("Failed to start recording:",o),r.messages.push({role:"assistant",content:"Unable to access microphone. Please check your permissions."}),b();}}async function re(o){let i=URL.createObjectURL(o),n=Array(40).fill(10),y=0;try{n=await oe(o);let l=new Audio(i);await new Promise(P=>{l.onloadedmetadata=()=>{y=l.duration,P();},l.onerror=()=>P();});}catch(l){console.error("Audio analysis failed",l);}r.messages.push({role:"user",content:"Voice message",audioUrl:i,audioDuration:y,waveformBars:n}),r.isLoading=true,b();try{let l=await e.chatWithAudio(o);return r.messages.push({role:"assistant",content:l.reply,products:l.products}),p.onMessage&&p.onMessage("Voice message",l),l}catch(l){throw r.messages.push({role:"assistant",content:"Sorry, I encountered an error processing your voice message. Please try again."}),l}finally{r.isLoading=false,b();}}function te(o){return /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(o)}function N(o){let i=Math.floor(o/60),n=Math.floor(o%60);return `${i}:${n.toString().padStart(2,"0")}`}async function oe(o){try{let i=new(window.AudioContext||window.webkitAudioContext),n=await o.arrayBuffer(),l=(await i.decodeAudioData(n)).getChannelData(0),P=40,g=Math.floor(l.length/P),U=[];for(let c=0;c<P;c++){let d=c*g,h=d+g,x=0;for(let v=d;v<h;v++)l[v]&&(x+=l[v]*l[v]);let k=Math.sqrt(x/g),S=Math.min(100,Math.max(10,k*400));U.push(S);}return U}catch(i){return console.error("Analysis error",i),Array.from({length:40},()=>20+Math.random()*60)}}async function A(o){r.messages.push({role:"user",content:o}),r.isLoading=true,b();try{let i=await e.chat(o);return r.messages.push({role:"assistant",content:i.reply,products:i.products}),p.onMessage&&p.onMessage(o,i),i}catch(i){throw r.messages.push({role:"assistant",content:"Sorry, I encountered an error. Please try again."}),i}finally{r.isLoading=false,b();}}function L(){r.isOpen=true,b(),p.onOpen?.(),setTimeout(()=>{s?.querySelector(".aicommerce-input")?.focus();},100);}function M(){r.isOpen=false,b(),p.onClose?.();}function ie(){r.isOpen?M():L();}function ae(){s&&(s.remove(),s=null),f&&(f.remove(),f=null);}function se(o){if(Object.assign(p,o),o.primaryColor){let i=D(p);f&&(f.textContent=i);}b();}function R(o){let i=document.createElement("div");return i.textContent=o,i.innerHTML}function ne(o,i){let y={USD:"$",EUR:"\u20AC",GBP:"\xA3",MAD:"DH",SAR:"SAR",AED:"AED",JPY:"\xA5",CNY:"\xA5"}[i||"USD"]||i||"$";return `${o.toFixed(2)} ${y}`}return G(),{open:L,close:M,toggle:ie,destroy:ae,sendMessage:A,updateConfig:se}}exports.AICommerceWidget=void 0;var F=B(()=>{$();V();exports.AICommerceWidget={init:j,VERSION:"1.0.0"};typeof window<"u"&&(window.AICommerceWidget=exports.AICommerceWidget);});$();F();var be="1.0.0";typeof window<"u"&&(window.AICommerce=($(),W(z)).AICommerce,window.AICommerceError=($(),W(z)).AICommerceError,window.AICommerceWidget=(F(),W(X)).AICommerceWidget);exports.VERSION=be;exports.createWidget=j;return exports;})({});//# sourceMappingURL=index.min.js.map
708
+ `}function Z(){if(!a)return;let o=a.querySelector(".aicommerce-launcher");o&&o.addEventListener("click",()=>M());let i=a.querySelector(".aicommerce-close");i&&i.addEventListener("click",()=>q());let c=a.querySelector(".aicommerce-input"),d=a.querySelector(".aicommerce-send");c&&c.addEventListener("keypress",n=>{n.key==="Enter"&&c.value.trim()&&(A(c.value.trim()),c.value="");}),d&&c&&d.addEventListener("click",()=>{c.value.trim()&&(A(c.value.trim()),c.value="");});let u=a.querySelector(".aicommerce-mic");u&&u.addEventListener("click",()=>ee()),a.querySelectorAll(".aicommerce-product-card").forEach(n=>{n.addEventListener("click",()=>{let m=n.getAttribute("data-product-id"),f=r.messages.flatMap(x=>x.products||[]).find(x=>x.id===m);f&&(l.onProductClick?l.onProductClick(f):f.url&&window.open(f.url,"_blank","noopener,noreferrer"));});}),a.querySelectorAll(".aicommerce-products").forEach(n=>{let m=false,f=0,x=0;n.addEventListener("mousedown",k=>{m=true,n.style.cursor="grabbing",f=k.pageX-n.offsetLeft,x=n.scrollLeft;}),n.addEventListener("mouseleave",()=>{m=false,n.style.cursor="grab";}),n.addEventListener("mouseup",()=>{m=false,n.style.cursor="grab";}),n.addEventListener("mousemove",k=>{if(!m)return;k.preventDefault();let v=(k.pageX-n.offsetLeft-f)*2;n.scrollLeft=x-v;});}),a.querySelectorAll(".aicommerce-audio-player").forEach(n=>{let m=n.querySelector("audio"),f=n.querySelector(".aicommerce-audio-btn"),x=n.querySelectorAll(".aicommerce-waveform-bar"),k=n.querySelector(".aicommerce-current-time");if(!m||!f)return;f.addEventListener("click",()=>{!m.paused?(m.pause(),f.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'):(a?.querySelectorAll("audio").forEach(w=>{if(w!==m&&!w.paused){w.pause();let $=w.closest(".aicommerce-audio-player")?.querySelector(".aicommerce-audio-btn");$&&($.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');}}),m.play(),f.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');}),m.addEventListener("timeupdate",()=>{if(k&&(k.textContent=K(m.currentTime)),m.duration){let v=m.currentTime/m.duration*100;x.forEach((w,U)=>{U/x.length*100<=v?w.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,1)":"var(--aic-primary)":w.style.backgroundColor=n.closest(".aicommerce-user")?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)";});}}),m.addEventListener("ended",()=>{f.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';});let S=n.querySelector(".aicommerce-waveform-bars");S&&S.addEventListener("click",v=>{let w=S.getBoundingClientRect(),$=(v.clientX-w.left)/w.width;m.duration&&(m.currentTime=$*m.duration);});});}async function ee(){if(r.isRecording)s&&s.state!=="inactive"&&s.stop();else try{let o=await navigator.mediaDevices.getUserMedia({audio:!0});g=[],s=new MediaRecorder(o,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),s.ondataavailable=i=>{i.data.size>0&&g.push(i.data);},s.onstop=async()=>{if(o.getTracks().forEach(i=>i.stop()),g.length>0){let i=new Blob(g,{type:s?.mimeType||"audio/webm"});await re(i);}r.isRecording=!1,y();},s.start(),r.isRecording=!0,y();}catch(o){console.error("Failed to start recording:",o),r.messages.push({role:"assistant",content:"Unable to access microphone. Please check your permissions."}),y();}}async function re(o){let i=URL.createObjectURL(o),c=Array(40).fill(10),d=0;try{c=await oe(o);let u=new Audio(i);await new Promise(P=>{u.onloadedmetadata=()=>{d=u.duration,P();},u.onerror=()=>P();});}catch(u){console.error("Audio analysis failed",u);}r.messages.push({role:"user",content:"Voice message",audioUrl:i,audioDuration:d,waveformBars:c}),r.isLoading=true,y();try{let u=await e.chatWithAudio(o);return r.messages.push({role:"assistant",content:u.reply,products:u.products}),l.onMessage&&l.onMessage("Voice message",u),u}catch(u){throw r.messages.push({role:"assistant",content:"Sorry, I encountered an error processing your voice message. Please try again."}),u}finally{r.isLoading=false,y();}}function te(o){return /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(o)}function K(o){let i=Math.floor(o/60),c=Math.floor(o%60);return `${i}:${c.toString().padStart(2,"0")}`}async function oe(o){try{let i=new(window.AudioContext||window.webkitAudioContext),c=await o.arrayBuffer(),u=(await i.decodeAudioData(c)).getChannelData(0),P=40,T=Math.floor(u.length/P),h=[];for(let n=0;n<P;n++){let m=n*T,f=m+T,x=0;for(let v=m;v<f;v++)u[v]&&(x+=u[v]*u[v]);let k=Math.sqrt(x/T),S=Math.min(100,Math.max(10,k*400));h.push(S);}return h}catch(i){return console.error("Analysis error",i),Array.from({length:40},()=>20+Math.random()*60)}}async function A(o){r.messages.push({role:"user",content:o}),r.isLoading=true,y();try{let i=await e.chat(o);return r.messages.push({role:"assistant",content:i.reply,products:i.products}),l.onMessage&&l.onMessage(o,i),i}catch(i){throw r.messages.push({role:"assistant",content:"Sorry, I encountered an error. Please try again."}),i}finally{r.isLoading=false,y();}}function M(){r.isOpen=true,y(),l.onOpen?.(),setTimeout(()=>{a?.querySelector(".aicommerce-input")?.focus();},100);}function q(){r.isOpen=false,y(),l.onClose?.();}function ie(){r.isOpen?q():M();}function ae(){a&&(a.remove(),a=null),b&&(b.remove(),b=null);}function se(o){if(Object.assign(l,o),o.primaryColor){let i=H(l);b&&(b.textContent=i);}y();}function R(o){let i=document.createElement("div");return i.textContent=o,i.innerHTML}function ne(o,i){let d={USD:"$",EUR:"\u20AC",GBP:"\xA3",MAD:"DH",SAR:"SAR",AED:"AED",JPY:"\xA5",CNY:"\xA5"}[i||"USD"]||i||"$";return `${o.toFixed(2)} ${d}`}return G(),{open:M,close:q,toggle:ie,destroy:ae,sendMessage:A,updateConfig:se}}exports.AICommerceWidget=void 0;var F=B(()=>{L();V();exports.AICommerceWidget={init:j,VERSION:"1.0.0"};typeof window<"u"&&(window.AICommerceWidget=exports.AICommerceWidget);});L();F();var be="1.0.0";typeof window<"u"&&(window.AICommerce=(L(),W(D)).AICommerce,window.AICommerceError=(L(),W(D)).AICommerceError,window.AICommerceWidget=(F(),W(X)).AICommerceWidget);exports.VERSION=be;exports.createWidget=j;return exports;})({});//# sourceMappingURL=index.min.js.map
653
709
  //# sourceMappingURL=index.min.js.map
package/dist/index.cjs CHANGED
@@ -902,6 +902,62 @@ function createWidgetStyles(config) {
902
902
  .aicommerce-messages::-webkit-scrollbar-thumb:hover {
903
903
  background: var(--aic-text-secondary);
904
904
  }
905
+
906
+ /* ============================================
907
+ Embedded Mode Styles
908
+ ============================================ */
909
+
910
+ /* Embedded container - position relative, inline flow */
911
+ #aicommerce-widget.aicommerce-embedded {
912
+ position: relative;
913
+ bottom: auto;
914
+ left: auto;
915
+ right: auto;
916
+ width: 100%;
917
+ height: var(--aic-height, 500px);
918
+ }
919
+
920
+ /* Embedded mode: hide launcher button */
921
+ .aicommerce-embedded .aicommerce-launcher {
922
+ display: none !important;
923
+ }
924
+
925
+ /* Embedded mode: chat is always visible and fills container */
926
+ .aicommerce-embedded .aicommerce-chat {
927
+ position: relative;
928
+ width: 100%;
929
+ height: 100%;
930
+ max-width: 100%;
931
+ max-height: 100%;
932
+ border-radius: var(--aic-radius);
933
+ transform: none !important;
934
+ opacity: 1 !important;
935
+ pointer-events: auto !important;
936
+ }
937
+
938
+ /* Embedded mode: no open/close animations */
939
+ .aicommerce-embedded .aicommerce-chat.aicommerce-closed {
940
+ opacity: 1 !important;
941
+ transform: none !important;
942
+ pointer-events: auto !important;
943
+ }
944
+
945
+ /* Embedded mode: messages area adjusts to container */
946
+ .aicommerce-embedded .aicommerce-messages {
947
+ flex: 1;
948
+ min-height: 0;
949
+ }
950
+
951
+ /* Embedded mode responsive */
952
+ @media (max-width: 420px) {
953
+ #aicommerce-widget.aicommerce-embedded {
954
+ height: var(--aic-height, 400px);
955
+ }
956
+
957
+ .aicommerce-embedded .aicommerce-chat {
958
+ border-radius: 12px;
959
+ }
960
+ }
905
961
  `;
906
962
  }
907
963
  function injectStyles(css) {
@@ -972,10 +1028,15 @@ function createWidget(config) {
972
1028
  }
973
1029
  async function initialize() {
974
1030
  state.storeConfig = await fetchStoreConfig();
1031
+ const displayMode = config.displayMode || "widget";
1032
+ const isEmbedded = displayMode === "embedded";
975
1033
  resolvedConfig = {
976
1034
  apiKey: config.apiKey,
977
1035
  storeId: config.storeId,
978
1036
  baseUrl: config.baseUrl || detectBaseUrl(),
1037
+ displayMode,
1038
+ container: config.container,
1039
+ height: config.height || "500px",
979
1040
  position: config.position || "bottom-right",
980
1041
  theme: config.theme || "auto",
981
1042
  primaryColor: config.primaryColor || state.storeConfig?.primaryColor || "#6366f1",
@@ -991,10 +1052,29 @@ function createWidget(config) {
991
1052
  };
992
1053
  const styles = createWidgetStyles(resolvedConfig);
993
1054
  styleElement = injectStyles(styles);
994
- container = document.createElement("div");
995
- container.id = "aicommerce-widget";
996
- container.className = `aicommerce-widget aicommerce-${resolvedConfig.position} aicommerce-theme-${resolvedConfig.theme}`;
997
- document.body.appendChild(container);
1055
+ if (isEmbedded) {
1056
+ let targetContainer = null;
1057
+ if (typeof config.container === "string") {
1058
+ targetContainer = document.querySelector(config.container);
1059
+ } else if (config.container instanceof HTMLElement) {
1060
+ targetContainer = config.container;
1061
+ }
1062
+ if (!targetContainer) {
1063
+ console.error("[AI Commerce] Embedded mode requires a valid container element or selector");
1064
+ return;
1065
+ }
1066
+ container = document.createElement("div");
1067
+ container.id = "aicommerce-widget";
1068
+ container.className = `aicommerce-widget aicommerce-embedded aicommerce-theme-${resolvedConfig.theme}`;
1069
+ container.style.setProperty("--aic-height", resolvedConfig.height);
1070
+ targetContainer.appendChild(container);
1071
+ state.isOpen = true;
1072
+ } else {
1073
+ container = document.createElement("div");
1074
+ container.id = "aicommerce-widget";
1075
+ container.className = `aicommerce-widget aicommerce-${resolvedConfig.position} aicommerce-theme-${resolvedConfig.theme}`;
1076
+ document.body.appendChild(container);
1077
+ }
998
1078
  render();
999
1079
  state.messages.push({
1000
1080
  role: "assistant",
@@ -1005,8 +1085,9 @@ function createWidget(config) {
1005
1085
  }
1006
1086
  function render() {
1007
1087
  if (!container) return;
1088
+ const isEmbedded = resolvedConfig.displayMode === "embedded";
1008
1089
  const html = `
1009
- ${!resolvedConfig.hideLauncher ? `
1090
+ ${!isEmbedded && !resolvedConfig.hideLauncher ? `
1010
1091
  <button class="aicommerce-launcher ${state.isOpen ? "aicommerce-hidden" : ""}" aria-label="Open chat">
1011
1092
  <span class="aicommerce-launcher-icon">${resolvedConfig.buttonText}</span>
1012
1093
  </button>
@@ -1023,7 +1104,7 @@ function createWidget(config) {
1023
1104
  <span class="aicommerce-status">Online</span>
1024
1105
  </div>
1025
1106
  </div>
1026
- <button class="aicommerce-close" aria-label="Close chat">\u2715</button>
1107
+ ${!isEmbedded ? `<button class="aicommerce-close" aria-label="Close chat">\u2715</button>` : ""}
1027
1108
  </div>
1028
1109
 
1029
1110
  <div class="aicommerce-messages">