@gengage/assistant-fe 0.6.14 → 0.6.17

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.
Files changed (40) hide show
  1. package/dist/agentic/adaptor/fetch-bridge.d.ts +20 -1
  2. package/dist/agentic/index.js +517 -367
  3. package/dist/agentic/worker.js +18 -18
  4. package/dist/agentic.iife.js +5 -5
  5. package/dist/{api-paths-kwROurUu.js → api-paths-xsHH9jtm.js} +1 -1
  6. package/dist/chat/components/InlineLauncher.d.ts +152 -0
  7. package/dist/chat/index.d.ts +2 -0
  8. package/dist/chat/runtime.d.ts +3 -0
  9. package/dist/chat/types.d.ts +6 -0
  10. package/dist/chat-runtime.js +9 -9
  11. package/dist/chat.iife.js +160 -35
  12. package/dist/chat.js +13 -12
  13. package/dist/common/overlay.d.ts +2 -0
  14. package/dist/{common-DZuPNgWh.js → common-O0BUdXOn.js} +2 -2
  15. package/dist/common.js +7 -7
  16. package/dist/{connection-warning-Bg4gn-cq.js → connection-warning-DWMfjv0Y.js} +1 -1
  17. package/dist/{fastIntent-BSgLJDlW.js → fastIntent-RTSVRJhw.js} +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +16 -16
  20. package/dist/{native-webview-DbKq9lN8.js → native-webview-U9HtGabb.js} +1 -1
  21. package/dist/native.iife.js +140 -15
  22. package/dist/native.js +1 -1
  23. package/dist/{overlay-CyoB1K0w.js → overlay-ClYgI2Kl.js} +5 -5
  24. package/dist/overlay.js +1 -1
  25. package/dist/qna-runtime.js +1 -1
  26. package/dist/qna.iife.js +1 -1
  27. package/dist/qna.js +1 -1
  28. package/dist/{request-text-su3Vlhrs.js → request-text-DThlE-Xd.js} +106 -106
  29. package/dist/{runtime-CAJp9Ehc.js → runtime-BKU-NQXf.js} +2101 -1745
  30. package/dist/{runtime-KV5wCTc-.js → runtime-COh3CwNU.js} +3 -3
  31. package/dist/{runtime-DwQSV54I.js → runtime-n7fEJGDt.js} +3 -3
  32. package/dist/{simbut-Bm96zEAo.js → simbut-DaFCfvp7.js} +1 -1
  33. package/dist/simbut.iife.js +1 -1
  34. package/dist/simbut.js +1 -1
  35. package/dist/{simrel-C9sM9CCV.js → simrel-CX1JBDa5.js} +1 -1
  36. package/dist/simrel-runtime.js +1 -1
  37. package/dist/simrel.iife.js +1 -1
  38. package/dist/simrel.js +2 -2
  39. package/dist/{widget-base-TZjXRr3u.js → widget-base-DoZrhVze.js} +1 -1
  40. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { A as E, B as J, C as B, D as F, E as I, F as M, H as j, I as x, L, M as g, N as z, O as R, P as h, R as C, S as A, T as q, U as D, V as K, _ as O, a as W, b as G, c as H, d as N, f as Q, g as V, h as _, i as X, j as T, k as Y, l as Z, m as $, n as ee, o as te, p as re, r as oe, s as ae, t as ne, u as ie, v as ce, w as le, x as se, y as de, z as ue } from "../request-text-su3Vlhrs.js";
1
+ import { A as E, B as J, C as B, D as F, E as I, F as M, H as j, I as x, L, M as g, N as z, O as R, P as h, R as C, S as A, T as q, U as D, V as K, _ as O, a as W, b as G, c as H, d as N, f as Q, g as V, h as _, i as X, j as T, k as Y, l as Z, m as $, n as ee, o as te, p as re, r as oe, s as ae, t as ne, u as ie, v as ce, w as le, x as se, y as de, z as ue } from "../request-text-DThlE-Xd.js";
2
2
  function pe(n) {
3
3
  const a = self, i = /* @__PURE__ */ new Map(), c = K(a), y = A(c);
4
4
  let t = null, u = null, l = null, p = "";
@@ -90,14 +90,14 @@ export {
90
90
  g as AgentError,
91
91
  C as ContextStore,
92
92
  q as action,
93
- _ as actionButtonsUiSpec,
93
+ ie as actionButtonsUiSpec,
94
94
  z as beErrorToAgentError,
95
- ae as buildPhotoSimilarityProfile,
96
- H as buildProductSimilarityProfile,
97
- Z as buildSimilarityQueries,
95
+ ee as buildPhotoSimilarityProfile,
96
+ oe as buildProductSimilarityProfile,
97
+ X as buildSimilarityQueries,
98
98
  h as caughtToStreamError,
99
- V as comparisonUiSpec,
100
- $ as createFlow,
99
+ N as comparisonUiSpec,
100
+ Z as createFlow,
101
101
  x as createJwtProvider,
102
102
  A as createToolBridge,
103
103
  K as createWorkerRpc,
@@ -107,27 +107,27 @@ export {
107
107
  j as handleMainRpc,
108
108
  M as httpErrorToAgentError,
109
109
  T as invokeBeOp,
110
- ee as llmCacheKey,
110
+ $ as llmCacheKey,
111
111
  R as metadata,
112
112
  L as mintDevJwt,
113
113
  de as normalizeProduct,
114
- ie as normalizeSimilarityText,
114
+ W as normalizeSimilarityText,
115
115
  J as nowIso,
116
- O as productDetailsUiSpec,
117
- oe as productFactsKey,
118
- X as productSkuKey,
119
- ce as productsUiSpec,
120
- N as rankSimilarProducts,
116
+ Q as productDetailsUiSpec,
117
+ _ as productFactsKey,
118
+ V as productSkuKey,
119
+ re as productsUiSpec,
120
+ te as rankSimilarProducts,
121
121
  ne as requestText,
122
122
  le as resolveFlow,
123
123
  D as runMainRpc,
124
124
  B as runTurn,
125
- Q as scoreSimilarityCandidate,
126
- W as stableKey,
125
+ ae as scoreSimilarityCandidate,
126
+ O as stableKey,
127
127
  pe as startWorker,
128
128
  Y as textChunk,
129
- te as textKey,
130
- re as tokenizeSimilarityText,
129
+ ce as textKey,
130
+ H as tokenizeSimilarityText,
131
131
  G as trimProductFactsCore,
132
132
  se as trimProductFactsListCore,
133
133
  E as uiSpec
@@ -1,5 +1,5 @@
1
- (function(y){Object.defineProperty(y,Symbol.toStringTag,{value:"Module"});function Je(e){return!!e&&typeof e=="object"&&e.type==="rpc.req"}function Ge({worker:e,tools:t={},beacon:r,memory:n=sessionStorage}){e.addEventListener("message",o=>{const i=o.data;Je(i)&&He(e,i,{tools:t,beacon:r,memory:n})})}async function He(e,t,r){try{const n=await ie(t.method,t.payload,r);e.postMessage({type:"rpc.result",rpcId:t.rpcId,ok:!0,value:n})}catch(n){e.postMessage({type:"rpc.result",rpcId:t.rpcId,ok:!1,error:{message:n instanceof Error?n.message:String(n)}})}}function We(e){if(e&&typeof e=="object"&&typeof e.name=="string")return e;throw new Error("tool.invoke requires { name, input }")}function Ve(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.get requires { key }")}function Ye(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.set requires { key }")}async function ie(e,t,{tools:r,beacon:n,memory:o}){if(e==="tool.invoke"){const{name:i,input:a}=We(t),c=r[i];if(typeof c!="function")throw new Error(`Unknown tool: ${i}`);return c(a)}if(e==="beacon.send")return n?.(t),{sent:!0};if(e==="memory.get"){const{key:i}=Ve(t),a=o.getItem(String(i));return a?JSON.parse(a):null}if(e==="memory.set"){const{key:i,value:a}=Ye(t);return o.setItem(String(i),JSON.stringify(a??null)),{ok:!0}}throw new Error(`Unknown RPC method: ${e}`)}function ae(){return new Date().toISOString()}function C(e){return Math.max(0,Math.round(performance.now()-e))}function M(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Qe(e){const{accountId:t,locale:r="en-GB",parentUrl:n="",threadId:o,incomingContext:i}=e,a=M(i)?i:{},c=M(a.thread)?a.thread:{},f=M(a.panel)?a.panel:{},m=M(a.meta)?a.meta:{},d=ce(a.messages),s={id:String(o||c.id||self.crypto.randomUUID()),started_at:String(c.started_at||ae()),extensions:M(c.extensions)?{...c.extensions}:{}},u=String(m.locale||r),l=String(m.parentUrl||n||typeof self<"u"&&self.location?.href||"");return{panel:{...f},messages:d,thread:s,meta:{locale:u,parentUrl:l,accountId:t}}}function Xe(e,t){const r=ce([t])[0];return r?{...e,messages:[...e.messages,r].slice(-50)}:e}function ce(e){return Array.isArray(e)?e.map(t=>{const r=t?.role;return{role:r==="model"?"assistant":typeof r=="string"?r:"",content:String(t?.content||"")}}).filter(t=>(t.role==="user"||t.role==="assistant")&&!!t.content).slice(-50):[]}var Ze="gengage:agent:context:";async function et({accountId:e,threadId:t,rpc:r}){const n=await r("memory.get",{tier:"session",key:se(e,t)});return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}async function tt({accountId:e,threadId:t,extensions:r,panel:n,rpc:o}){await o("memory.set",{tier:"session",key:se(e,t),value:{thread:{extensions:r},...n&&Object.keys(n).length>0?{panel:n}:{}}})}function se(e,t){return`${Ze}${e}:${t}`}function b(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var ue=class{#e=new Map;#t;#n;#o;#r;#i;constructor({accountId:e,locale:t,parentUrl:r,rpc:n,persistentPanelKeys:o=[]}){this.#t=e,this.#n=t,this.#o=r,this.#r=n,this.#i=[...new Set(o.filter(Boolean))]}async load(e){const t=e?.meta?.threadId||e?.session_id||e?.sessionId,r=String(t||"default"),n=this.#e.get(r);if(n)return n;const o=await et({accountId:this.#t,threadId:r,rpc:this.#r}),i=Qe({accountId:this.#t,locale:e?.locale||this.#n,parentUrl:this.#o,threadId:r,incomingContext:nt(o,e?.context)});return this.#e.set(r,i),i}patch(e,t){const r=String(e||"default"),n=this.#e.get(r);if(!n)return null;const o=le(n,typeof t=="function"?t(n):t);return this.#e.set(r,o),o}appendUserMessage(e,t){const r=String(e||"default");if(!t)return this.#e.get(r)??null;const n=this.#e.get(r);if(!n)return null;const o=Xe(n,{role:"user",content:t});return this.#e.set(r,o),o}async commit(e){const t=String(e||"default"),r=this.#e.get(t);return r?(await tt({accountId:this.#t,threadId:t,extensions:r.thread.extensions,panel:rt(r.panel,this.#i),rpc:this.#r}),r):null}};function rt(e,t){if(!t.length||!b(e))return;const r={};for(const n of t)Object.prototype.hasOwnProperty.call(e,n)&&(r[n]=e[n]);return r}function nt(e,t){return!b(e)&&!b(t)?{}:le(b(e)?e:{},b(t)?t:{})}function le(e,t){if(!b(t))return e;const r=e,n=t,o=b(r.panel)?r.panel:{},i=b(n.panel)?n.panel:{},a=b(r.thread)?r.thread:{},c=b(n.thread)?n.thread:{},f=b(a.extensions)?a.extensions:{},m=b(c.extensions)?c.extensions:{},d=b(r.meta)?r.meta:{},s=b(n.meta)?n.meta:{};return{...e,...t,panel:{...o,...i},thread:{...a,...c,extensions:{...f,...m}},meta:{...d,...s},messages:Array.isArray(n.messages)?n.messages.slice(-50):e.messages??[]}}function de(e){const t=String.fromCharCode(...e);return btoa(t).replace(/\+/gu,"-").replace(/\//gu,"_").replace(/=+$/u,"")}function fe(e){return de(new TextEncoder().encode(JSON.stringify(e)))}async function ot({accountId:e,devJwtSecret:t,ttlS:r=300}){if(!t)throw new Error("devJwtSecret is required for local agent mode.");const n=Math.floor(Date.now()/1e3),o=`${fe({alg:"HS256",typ:"JWT"})}.${fe({sub:e,iat:n,exp:n+r,scope:"invoke",jti:crypto.randomUUID?.()||`${n}-${Math.random()}`})}`,i=await crypto.subtle.importKey("raw",new TextEncoder().encode(t),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),a=await crypto.subtle.sign("HMAC",i,new TextEncoder().encode(o));return`${o}.${de(new Uint8Array(a))}`}function me({accountId:e,devJwtSecret:t,tokenBrokerUrl:r,tokenBrokerAudience:n,refreshSkewS:o=30,fetchImpl:i=fetch}){let a=null;return async({signal:c,parentUrl:f}={})=>{if(t)return ot({accountId:e,devJwtSecret:t});if(!r)throw new Error("tokenBrokerUrl is required for production agent mode.");const m=Math.floor(Date.now()/1e3);return a?.token&&a.expiresAtS-o>m||(a=await it({accountId:e,tokenBrokerUrl:r,tokenBrokerAudience:n,parentUrl:f,signal:c,fetchImpl:i})),a.token}}async function it({accountId:e,tokenBrokerUrl:t,tokenBrokerAudience:r,parentUrl:n,signal:o,fetchImpl:i}){const a=await i(t,{method:"POST",credentials:"include",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({accountId:e,scope:"invoke",audience:r||void 0,parentUrl:n||void 0}),...o?{signal:o}:{}});if(!a.ok)throw new Error(`Token broker request failed (${a.status}).`);const c=await a.json(),f=c?.token||c?.jwt||c?.access_token;if(!f||typeof f!="string")throw new Error("Token broker response did not include a JWT.");return{token:f,expiresAtS:at(c)||ct(f)||Math.floor(Date.now()/1e3)+300}}function at(e){const t=e?.expiresAtS??e?.expires_at_s??e?.expiresInS??e?.expires_in_s;if(Number.isFinite(t))return Number(t);const r=e?.expiresIn??e?.expires_in;if(Number.isFinite(r))return Math.floor(Date.now()/1e3)+Number(r);const n=e?.expiresAt??e?.expires_at;if(typeof n=="string"){const o=Date.parse(n);if(Number.isFinite(o))return Math.floor(o/1e3)}return null}function ct(e){try{const[,t]=e.split(".");if(!t)return null;const r=t.replace(/-/gu,"+").replace(/_/gu,"/"),n=atob(r.padEnd(Math.ceil(r.length/4)*4,"=")),o=JSON.parse(n);return Number.isFinite(o?.exp)?Number(o.exp):null}catch{return null}}var ye={unauthorized:{code:"auth",message:"Assistant authentication failed. Please retry."},forbidden:{code:"auth",message:"Assistant authentication failed. Please retry."},unknown_op:{code:"op_unavailable",message:"This assistant action is not available yet."},invalid_input:{code:"invalid_request",message:"The assistant request was not valid."},account_config:{code:"account_config",message:"Assistant configuration is unavailable."},upstream_llm:{code:"op_failed",message:"The assistant could not complete that request."},upstream_timeout:{code:"op_timeout",message:"The assistant took too long to respond."},schema_mismatch:{code:"op_failed",message:"The assistant could not complete that request."},rate_limited:{code:"rate_limited",message:"The assistant is receiving too many requests. Please retry shortly."},internal:{code:"op_failed",message:"The assistant could not complete that request."},payload_too_large:{code:"invalid_request",message:"The assistant request was too large."}},D=class extends Error{constructor(e,t,r={}){super(t),this.name="AgentError",this.code=e,this.source=r.source||"agent",r.sourceCode&&(this.sourceCode=r.sourceCode),r.detail!==void 0&&(this.detail=r.detail)}};function z(e){const t=String(e?.code||"upstream_llm"),r=ye[t]||ye.upstream_llm;return new D(r.code,r.message,{source:"be",sourceCode:t,detail:e?.detail})}function pe(e,t){const r=t?.error&&typeof t.error=="object"?t.error:{};return z({code:String(r.code||st(e)),detail:r.detail})}function ge(e){return e instanceof D?{type:"error",code:e.code,message:e.message}:{type:"error",code:"agent_invoke_failed",message:"The assistant could not complete that request."}}function st(e){return e===401?"unauthorized":e===403?"forbidden":e===413?"payload_too_large":e===429?"rate_limited":"internal"}var ut=7200*1e3,he=200,lt=5*1024*1024,dt="gengage_request_response_cache",ft=1,_="responses",mt=new Set(["addToCart","like"]),E=new Map,we=null;async function yt(e,t={},r={}){const n=pt(e,t);if(!n)return fetch(e,t);const o=Date.now(),i=await ht(n,o);if(i)return St(i);const a=await fetch(e,t);return a.ok&&wt(n,a.clone(),o,{ttlMs:r.ttlMs??ut,maxEntries:r.maxEntries??he,maxBodyBytes:r.maxBodyBytes??lt}),a}function pt(e,t={}){if(typeof Request<"u"&&e instanceof Request)return null;const r=String(t.method||"GET").toUpperCase();return r!=="POST"||typeof t.body!="string"||gt(t.body)?null:`rr:${Pt(Tt({url:String(e),method:r,headers:kt(t.headers),body:t.body}))}`}function gt(e){try{const t=JSON.parse(e);if(!t||typeof t!="object"||Array.isArray(t))return!1;const r=t.type;return typeof r=="string"&&mt.has(r)}catch{return!1}}async function ht(e,t){const r=E.get(e);if(r)if(r.expiresAt<=t)E.delete(e);else return r.lastAccessedAt=t,E.delete(e),E.set(e,r),J(r),r;const n=await _t(e);return n?n.expiresAt<=t?(E.delete(e),Et(e),null):(n.lastAccessedAt=t,E.set(e,n),J(n),be(he),n):null}async function wt(e,t,r,n){try{const o=await t.text();if(It(o)>n.maxBodyBytes||bt(o))return;const i={key:e,status:t.status,statusText:t.statusText,headers:At(t.headers),body:o,createdAt:r,expiresAt:r+n.ttlMs,lastAccessedAt:r};E.set(e,i),be(n.maxEntries),await J(i),await xt(n.maxEntries,r)}catch{}}function bt(e){return/"_error"\s*:/u.test(e)||/"type"\s*:\s*"error"/u.test(e)}function St(e){return new Response(e.body,{status:e.status,statusText:e.statusText,headers:new Headers(e.headers)})}function kt(e){const t=new Headers(e),r=[];return t.forEach((n,o)=>{const i=o.toLowerCase();i!=="authorization"&&i!=="cookie"&&r.push([i,n])}),r.sort(([n],[o])=>n.localeCompare(o))}function At(e){const t=[];return e.forEach((r,n)=>{const o=n.toLowerCase();o!=="set-cookie"&&t.push([o,r])}),t.sort(([r],[n])=>r.localeCompare(n))}function be(e){for(;E.size>e;){const t=[...E.values()].sort((r,n)=>r.lastAccessedAt-n.lastAccessedAt)[0];if(!t)break;E.delete(t.key)}}async function L(){return typeof indexedDB>"u"?null:(we??=new Promise(e=>{const t=indexedDB.open(dt,ft);t.onupgradeneeded=()=>{const r=t.result;r.objectStoreNames.contains(_)||r.createObjectStore(_,{keyPath:"key"}).createIndex("lastAccessedAt","lastAccessedAt",{unique:!1})},t.onsuccess=()=>e(t.result),t.onerror=()=>e(null),t.onblocked=()=>e(null)}),we)}async function _t(e){const t=await L();return t?new Promise(r=>{const n=t.transaction(_,"readonly"),o=n.objectStore(_).get(e);o.onsuccess=()=>r(o.result??null),o.onerror=()=>r(null),n.onerror=()=>r(null)}):null}async function J(e){const t=await L();t&&await new Promise(r=>{const n=t.transaction(_,"readwrite");n.objectStore(_).put(e),n.oncomplete=()=>r(),n.onerror=()=>r(),n.onabort=()=>r()})}async function Et(e){const t=await L();t&&await new Promise(r=>{const n=t.transaction(_,"readwrite");n.objectStore(_).delete(e),n.oncomplete=()=>r(),n.onerror=()=>r(),n.onabort=()=>r()})}async function xt(e,t){const r=await L();r&&await new Promise(n=>{const o=r.transaction(_,"readwrite"),i=o.objectStore(_),a=[],c=i.openCursor();c.onsuccess=()=>{const f=c.result;if(!f){const m=a.filter(s=>s.expiresAt<=t),d=a.filter(s=>s.expiresAt>t).sort((s,u)=>s.lastAccessedAt-u.lastAccessedAt).slice(0,Math.max(0,a.length-m.length-e));for(const s of[...m,...d])i.delete(s.key);return}a.push(f.value),f.continue()},c.onerror=()=>n(),o.oncomplete=()=>n(),o.onerror=()=>n(),o.onabort=()=>n()})}function Tt(e){return JSON.stringify(G(e))}function G(e){return Array.isArray(e)?e.map(G):!e||typeof e!="object"?e:Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,G(r)]))}function Pt(e){let t=14695981039346656037n;const r=1099511628211n;for(let n=0;n<e.length;n+=1)t^=BigInt(e.charCodeAt(n)),t=BigInt.asUintN(64,t*r);return t.toString(16).padStart(16,"0")}function It(e){return typeof TextEncoder<"u"?new TextEncoder().encode(e).byteLength:e.length}async function jt({beUrl:e,accountId:t,devJwtSecret:r,tokenBrokerUrl:n,tokenBrokerAudience:o,jwtProvider:i,parentUrl:a,op:c,input:f,cacheTtlS:m,cacheKey:d,browserCache:s,signal:u}){const l=await(i||me({accountId:t,devJwtSecret:r,tokenBrokerUrl:n,tokenBrokerAudience:o}))({...u?{signal:u}:{},...a?{parentUrl:a}:{}}),{opDomain:p,opName:g}=Ct(c,t),h={method:"POST",headers:{authorization:`Bearer ${l}`,"content-type":"application/json",accept:"application/x-ndjson"},body:JSON.stringify({op_domain:p,op_name:g,op_payload:f,...m!==void 0?{cache_ttl_s:m}:{},...d!==void 0?{cache_key:d}:{}}),...u?{signal:u}:{}},k=`${String(e).replace(/\/+$/u,"")}/v1/execute`,w=s===!1?await fetch(k,h):await yt(k,h,typeof s=="object"?s:{});if(!w.ok)throw pe(w.status,await Rt(w));return Mt(w)}function Ct(e,t){if(!e||e.startsWith("-")||e.endsWith("-"))throw new Error(`Invalid BE op name: ${e}`);return{opDomain:Ot(t),opName:e}}function Ot(e){return e.replace(/-agentic$/u,"")}async function Rt(e){try{return await e.json()}catch{return{error:{code:e.statusText||"internal"}}}}async function Mt(e){const t=e.body?.getReader();if(!t)throw new Error("BE response body is not readable.");const r=new TextDecoder;let n="";const o={};for(;;){const{value:a,done:c}=await t.read();if(c)break;n+=r.decode(a,{stream:!0});let f=n.indexOf(`
2
- `);for(;f>=0;){const m=n.slice(0,f).trim();n=n.slice(f+1),m&&Se(JSON.parse(m),o),f=n.indexOf(`
3
- `)}}const i=n.trim();return i&&Se(JSON.parse(i),o),o}function Se(e,t){if(e._error)throw z(e._error);if(!e._end)for(const[r,n]of Object.entries(e)){if(Object.prototype.hasOwnProperty.call(t,r))throw new D("op_failed",`BE streamed duplicate field "${r}".`,{source:"be",sourceCode:"schema_mismatch"});t[r]=n}}function Ut(e={}){return{type:"metadata",...e}}function ke(e,t=!1,r={}){return{type:"text_chunk",content:e,final:t,...r}}function Bt(e){return{type:"ui_spec",...e}}function vt(e){return{type:"action",action:e}}function Ae(e,t){return{type:"error",code:e,message:t}}function H(){return{type:"done"}}function _e(e,t){return e[t?.type||t?.action?.type||"inputText"]||e.inputText}async function Nt({request:e,accountModule:t,contextStore:r,beClient:n,toolBridge:o,emit:i,rpc:a,signal:c}){const f=performance.now(),m=await r.load(e),d=m.thread.id,s=Yt(e);r.appendUserMessage(d,s);const u=_e(t.flows,e);if(!u)return i(Ae("unknown_action",`No agent flow for request type ${e?.type||"inputText"}`)),i(H()),{steps:0,productSkusEmitted:[]};const l={request:e,context:r.patch(d,{})||m,bag:{},accountConfig:t.accountConfig||{},threadId:d,steps:0,productSkusEmitted:new Set,committed:!1},p={contextStore:r,beClient:n,toolBridge:o,emit:i,rpc:a,adapters:t.adapters||{},...c?{signal:c}:{}};return await U(u,l,p),l.committed||await W(l,p),await a("beacon.send",{type:"turnSummary",threadId:d,sessionId:e?.session_id||e?.sessionId||d,accountId:t.accountId||l.context.meta.accountId,steps:l.steps,totalLatencyMs:C(f),productSkusEmitted:[...l.productSkusEmitted]}),{steps:l.steps,productSkusEmitted:[...l.productSkusEmitted]}}async function U(e,t,r){for(const n of e){if(r.signal?.aborted)return;t.steps+=1,await Dt(n,t,r),t.context=r.contextStore.patch(t.threadId,{})||t.context}}async function Dt(e,t,r){const n=Y(t);if(e.kind==="be_op"){await Lt(e,t,r,n);return}if(e.kind==="tool"){await $t(e,t,r,n);return}if(e.kind==="adapter"){await Ft(e,t,r,n);return}if(e.kind==="emit"){qt(e,t,r);return}if(e.kind==="branch"){await Kt(e,t,r,n);return}if(e.kind==="parallel"){await zt(e,t,r);return}if(e.kind==="refusal"){await Jt(e,t,r,n);return}e.kind==="commit"&&await Gt(e,t,r)}async function Lt(e,t,r,n){const o=performance.now();let i;const a=I(e.cacheTtlS,n),c=I(e.cacheKey,n),f=I(e.browserCache,n);try{i=await r.beClient.invoke({op:e.op,input:I(e.input,n),...a!==void 0?{cacheTtlS:a}:{},...c!==void 0?{cacheKey:c}:{},...f!==void 0?{browserCache:f}:{},...r.signal?{signal:r.signal}:{}})}catch(d){const s=d,u=String(s?.sourceCode||s?.code||"unknown"),l={type:"agentOp",threadId:t.threadId,sessionId:t.request?.session_id||t.request?.sessionId||t.threadId,accountId:t.context.meta.accountId,op:e.op,status:"error",latencyMs:C(o),errorCode:u};if(await r.rpc("beacon.send",l),e.onError){e.errorOut&&(t.bag[e.errorOut]=d),await U(e.onError,t,r);return}throw d}e.out&&(t.bag[e.out]=i),V(e,i,t,r.contextStore);const m={type:"agentOp",threadId:t.threadId,sessionId:t.request?.session_id||t.request?.sessionId||t.threadId,accountId:t.context.meta.accountId,op:e.op,status:"ok",latencyMs:C(o)};await r.rpc("beacon.send",m)}async function $t(e,t,r,n){const o=performance.now();try{const i=await r.toolBridge.invoke(e.name,I(e.input,n));e.out&&(t.bag[e.out]=i),V(e,i,t,r.contextStore),await r.rpc("beacon.send",{type:"agentTool",threadId:t.threadId,sessionId:Ee(t),accountId:t.context.meta.accountId,tool:e.name,status:"ok",latencyMs:C(o)})}catch(i){const a=i;if(await r.rpc("beacon.send",{type:"agentTool",threadId:t.threadId,sessionId:Ee(t),accountId:t.context.meta.accountId,tool:e.name,status:"error",latencyMs:C(o),errorCode:String(a?.code||a?.name||"unknown")}),e.onError){e.errorOut&&(t.bag[e.errorOut]=i),await U(e.onError,t,r);return}throw i}}async function Ft(e,t,r,n){const o=r.adapters?.[e.name];if(typeof o!="function")throw new Error(`Unknown flow adapter: ${e.name}`);const i=await o(I(e.input,n),n);e.out&&(t.bag[e.out]=i),V(e,i,t,r.contextStore)}function qt(e,t,r){const n=e.build(Y(t));Qt(n,t.productSkusEmitted),r.emit(n)}async function Kt(e,t,r,n){const o=String(I(e.on,n)||"default");await U(e.cases[o]||e.cases.default||[],t,r)}async function zt(e,t,r){const n=e.steps.map(a=>{const c={...t,context:Ht(t.context),bag:{...t.bag},productSkusEmitted:t.productSkusEmitted,committed:!1};return U(a,c,{...r,contextStore:Wt(c)}).then(()=>c)}),o=await Promise.all(n),i=e.merge||{};for(const a of o){for(const c of i.bag||[])Object.prototype.hasOwnProperty.call(a.bag,c)&&(t.bag[c]=a.bag[c]);if(i.panel?.length){const c=xe(a.context.panel,i.panel);Object.keys(c).length&&(t.context=r.contextStore.patch(t.threadId,{panel:c})||t.context)}if(i.threadExtensions?.length){const c=xe(a.context.thread.extensions,i.threadExtensions);Object.keys(c).length&&(t.context=r.contextStore.patch(t.threadId,{thread:{...t.context.thread,extensions:c}})||t.context)}}}async function Jt(e,t,r,n){r.emit(ke(I(e.message,n),!0)),await W(t,r)}async function Gt(e,t,r){await W(t,r)}async function W(e,{contextStore:t,emit:r}){e.committed||(e.context=await t.commit(e.threadId)||e.context,e.committed=!0,r(H()))}function V(e,t,r,n){if(typeof e.patch!="function")return;const o=e.patch(r.context,t,Y(r));o&&(r.context=n.patch(r.threadId,o)||r.context)}function Y(e){return{request:e.request,context:e.context,bag:e.bag,accountConfig:e.accountConfig}}function Ee(e){return e.request?.session_id||e.request?.sessionId||e.threadId}function Ht(e){return typeof structuredClone=="function"?structuredClone(e):JSON.parse(JSON.stringify(e))}function xe(e,t){const r={};for(const n of t)Object.prototype.hasOwnProperty.call(e,n)&&(r[n]=e[n]);return r}function Wt(e){return{async load(){return e.context},patch(t,r){return e.context=Vt(e.context,r),e.context},appendUserMessage(){return e.context},async commit(){return e.context}}}function Vt(e,t){return!t||typeof t!="object"?e:{...e,...t,panel:{...e.panel||{},...t.panel||{}},thread:{...e.thread||{},...t.thread||{},extensions:{...e.thread?.extensions||{},...t.thread?.extensions||{}}},meta:{...e.meta||{},...t.meta||{}},messages:Array.isArray(t.messages)?t.messages.slice(-50):e.messages}}function I(e,t){return typeof e=="function"?e(t):e}function Yt(e){const t=e?.payload;if(typeof t=="string")return t;if(t&&typeof t=="object"&&"text"in t){const r=t.text;if(typeof r=="string")return r}return typeof e?.action?.payload=="string"?e.action.payload:typeof e?.action?.title=="string"?e.action.title:""}function Qt(e,t){const r=e,n=r.spec,o=Array.isArray(n?.items)?n.items:void 0,i=Array.isArray(r.items)?r.items:void 0,a=o||i;if(Array.isArray(a)){for(const c of a)if(c&&typeof c=="object"){const f=c.sku;typeof f=="string"&&t.add(f)}}}function Xt(e){return{invoke(t,r){return e("tool.invoke",{name:t,input:r})}}}var Zt=512,er=.74;function Te({accountId:e,worker:t,beUrl:r,devJwtSecret:n,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,tools:c={},beacon:f}){let m=1;const d=new Map;return Ge({worker:t,tools:c,beacon:s=>f?.({...s,accountId:s.accountId||e}),memory:sessionStorage}),t.addEventListener("message",s=>{const u=s.data||{},l=typeof u.id=="number"?u.id:null;if(l==null)return;const p=d.get(l);if(p){if(u.type==="event"&&u.event){Q(p,u.event);return}if(u.type==="error"){p.onError(new Error(u.message||"Agent worker failed")),d.delete(l);return}u.type==="end"&&d.delete(l)}}),(s,u,l,p)=>{const g=m++;d.set(g,u);const h=()=>{d.delete(g),t.postMessage({id:g,type:"abort"})},k=w=>{if(l.aborted){h();return}t.postMessage({id:g,type:"invoke",accountId:e,beUrl:r,devJwtSecret:n,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,request:w,parentUrl:window.location.href})};if(l.aborted){h();return}if(l.addEventListener("abort",h,{once:!0}),p){Ie(s,p).then(k).catch(w=>{d.delete(g),u.onError(w instanceof Error?w:new Error("Failed to read image attachment"))});return}k(s)}}function Pe({accountId:e,accountModule:t,beUrl:r,devJwtSecret:n,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,tools:c={},beacon:f}){let m=null;const d=tr({accountId:e,tools:c,beacon:f}),s=Xt(d),u=me({accountId:e,...n?{devJwtSecret:n}:{},...o?{tokenBrokerUrl:o}:{},...i?{tokenBrokerAudience:i}:{}});return async(l,p,g,h)=>{const k=await Ie(l||{},h);m||=new ue({accountId:e,locale:k?.locale||a,parentUrl:window.location.href,rpc:d,persistentPanelKeys:t.contextPersistence?.panelKeys});try{await Nt({request:k,accountModule:{...t,accountId:e},contextStore:m,beClient:{invoke({op:w,input:oe,signal:ze,cacheTtlS:dn,cacheKey:fn,browserCache:mn}){return jt({beUrl:r,accountId:e,jwtProvider:u,parentUrl:window.location.href,op:w,input:oe,cacheTtlS:dn,cacheKey:fn,browserCache:mn,...ze?{signal:ze}:{}})}},toolBridge:s,emit:w=>Q(p,w),rpc:d,signal:g})}catch(w){g?.aborted||(Q(p,ge(w)),p.onDone())}}}function tr({accountId:e,tools:t,beacon:r}){const n=o=>r?.({...o,accountId:o.accountId||e});return((o,i)=>ie(o,i,{tools:t,beacon:n,memory:sessionStorage}))}async function Ie(e,t){if(!t||!t.type?.startsWith("image/"))return e;const r=await or(t),n={...rr(e.payload??e.action?.payload),image_data_url:r.dataUrl,image_mime:r.mime};return{...e,payload:n,...e.action?{action:{...e.action,payload:n}}:{}}}function rr(e){return nr(e)?{...e}:typeof e=="string"?{text:e}:{}}function nr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function or(e){const t=await ir(e);return t||{dataUrl:await je(e),mime:e.type}}async function ir(e){if(typeof createImageBitmap!="function"||typeof document>"u")return null;let t=null;try{t=await createImageBitmap(e);const r=Math.min(1,Zt/Math.max(t.width,t.height)),n=Math.max(1,Math.round(t.width*r)),o=Math.max(1,Math.round(t.height*r)),i=document.createElement("canvas");i.width=n,i.height=o;const a=i.getContext("2d");if(!a)return null;a.drawImage(t,0,0,n,o);const c=await new Promise(f=>i.toBlob(f,"image/jpeg",er));return c?{dataUrl:await je(c),mime:c.type||"image/jpeg"}:null}catch{return null}finally{t?.close()}}async function je(e){const t=new Uint8Array(await e.arrayBuffer());let r="";const n=32768;for(let o=0;o<t.length;o+=n)r+=String.fromCharCode(...t.subarray(o,o+n));return`data:${e.type};base64,${btoa(r)}`}function Q(e,t){switch(t?.type){case"text_chunk":{const r=t;e.onTextChunk(r.content||"",r.final===!0,r);break}case"ui_spec":{const r=t;e.onUISpec(r.spec,r.widget,r.panelHint,r.clearPanel===!0);break}case"action":e.onAction(t);break;case"metadata":e.onMetadata(t);break;case"error":e.onError(ar(t));break;case"done":e.onDone();break;default:break}}function ar(e){const t=new Error(e.message||e.code||"Agent error");return e.code&&(t.code=e.code),t}var $="__gengageAgentFetchBridge";function cr({accountId:e,streamTransport:t,endpoints:r={}}){if(!e)throw new Error("accountId is required.");if(typeof t!="function")throw new Error("streamTransport is required.");const n=sr(),o=`https://gengage-injector.invalid/${encodeURIComponent(e)}`,i=new Set,a=c=>{const f=`${o}/chat/${c}`;i.add(f);const m=r[c],d={streamTransport:t,endpoint:c};m&&(d.endpointHandler=m),n.routes.set(f,d)};a("process_action");for(const c of Object.keys(r))c!=="process_action"&&a(c);return{middlewareUrl:o,stop(){for(const c of i)n.routes.delete(c);ur(n)}}}function sr(){const e=window,t=e[$];if(t)return t;const r=e.fetch.bind(e),n={routes:new Map,originalFetch:r,installedFetch:r};return n.installedFetch=(o,i)=>{const a=Ce(o),c=n.routes.get(a);return c?dr(c,o,i):r(o,i)},e.fetch=n.installedFetch,e[$]=n,n}function ur(e){if(e.routes.size>0)return;const t=window;t.fetch===e.installedFetch&&(t.fetch=e.originalFetch),t[$]===e&&delete t[$]}function Ce(e){return typeof e=="string"?e:e instanceof URL?e.href:e?.url||""}function Oe(e,t){if(t?.signal)return t.signal;if(typeof Request<"u"&&e instanceof Request)return e.signal}function Re(e,t){return t?.body!==void 0&&t?.body!==null?t.body:typeof Request<"u"&&e instanceof Request?e.clone().text():null}async function lr(e,t){const r=Re(e,t);if(r instanceof FormData){const o=r.get("request"),i=r.get("attachment");return{request:JSON.parse(String(o||"{}")),...i instanceof File?{attachment:i}:{}}}const n=await Promise.resolve(r);return typeof n=="string"?{request:JSON.parse(n||"{}")}:{request:{}}}async function dr(e,t,r){if(e.endpoint&&e.endpoint!=="process_action"&&e.endpointHandler){const m=new AbortController,d=Oe(t,r);let s=null;if(d){const u=()=>m.abort();d.aborted&&u(),d.addEventListener("abort",u,{once:!0}),s=()=>d.removeEventListener("abort",u)}try{const u=await fr(t,r);return await e.endpointHandler(u,{accountId:mr(t),endpoint:e.endpoint,signal:m.signal})}finally{s?.()}}const n=new TextEncoder,o=new AbortController,i=Oe(t,r);let a=!1,c=null;const f=new ReadableStream({async start(m){const d=l=>{a||m.enqueue(n.encode(`${JSON.stringify(l)}
4
- `))},s=()=>{a||(a=!0,c?.(),m.close())},u=l=>{d({type:"error",code:l?.code||"agent_bridge_error",message:l instanceof Error?l.message:String(l)}),d({type:"done"}),s()};if(i){const l=()=>{o.abort(),a||(a=!0,c?.(),m.error(new DOMException("Aborted","AbortError")))};if(i.aborted){l();return}i.addEventListener("abort",l,{once:!0}),c=()=>i.removeEventListener("abort",l)}try{const{request:l,attachment:p}=await lr(t,r),g=e.streamTransport(l,{onTextChunk:(h,k,w={})=>d({type:"text_chunk",content:h,final:k===!0,...w}),onUISpec:(h,k,w,oe)=>d({type:"ui_spec",spec:h,widget:k,...w?{panelHint:w}:{},...oe?{clearPanel:!0}:{}}),onAction:h=>{d(h?.type==="action"?h:{type:"action",action:h})},onMetadata:h=>{d(h?.type==="metadata"?h:{type:"metadata",...h})},onError:u,onDone:()=>{d({type:"done"}),s()}},o.signal,p);yr(g)&&(await g,o.signal.aborted||(d({type:"done"}),s()))}catch(l){o.signal.aborted||u(l)}},cancel(){o.abort(),c?.(),a=!0}});return new Response(f,{status:200,headers:{"Content-Type":"application/x-ndjson"}})}async function fr(e,t){const r=await Promise.resolve(Re(e,t));return typeof r!="string"||r.trim()===""?{}:JSON.parse(r)}function mr(e){try{const[t]=new URL(Ce(e)).pathname.split("/").filter(Boolean);return decodeURIComponent(t||"")}catch{return""}}function yr(e){return e!==null&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function pr({accountId:e,beUrl:t,devJwtSecret:r,tokenBrokerUrl:n,tokenBrokerAudience:o,workerUrl:i,defaultLocale:a="en-GB",accountModule:c,tools:f={},beacon:m,allowBlobWorker:d=!1}){if(!e)throw new Error("accountId is required.");if(!t)throw new Error("beUrl is required. The injector owns backend URLs; the SDK has no default.");if(!i)throw new Error("workerUrl is required.");const s=window,u=s.GengageAssistantInjector||(s.GengageAssistantInjector={}),l=u[e]||(u[e]={});if(l.agentController)return l.agentController;const p=X(i)||d?Me(i,`gengage-${e}-agent`,{allowBlobWorker:d}):null;p||m?.({type:"agentRuntime",accountId:e,transport:"main-thread",reason:"cross-origin-worker-url",workerUrl:i}),l.streamTransport=p?Te({accountId:e,worker:p.worker,beUrl:t,...r?{devJwtSecret:r}:{},...n?{tokenBrokerUrl:n}:{},...o?{tokenBrokerAudience:o}:{},defaultLocale:a,tools:f,...m?{beacon:m}:{}}):Pe({accountId:e,accountModule:c,beUrl:t,...r?{devJwtSecret:r}:{},...n?{tokenBrokerUrl:n}:{},...o?{tokenBrokerAudience:o}:{},defaultLocale:a,tools:f,...m?{beacon:m}:{}});const g={type:"agent",stop(){delete l.streamTransport,p?.worker.terminate(),p?.cleanup(),delete l.agentController},diagnostics(){return{accountId:e,beUrl:t,workerUrl:i,mounted:!0,transport:p?"worker":"main-thread",transportReason:p?"module-worker":"cross-origin-worker-url",flows:Object.keys(c?.flows||{})}}};return l.agentController=g,g}function X(e){const t=new URL(e,window.location.href);return t.origin===window.location.origin||t.protocol==="blob:"}function Me(e,t,r={}){const n=new URL(e,window.location.href);if(X(e))return{worker:new Worker(n.href,{type:"module",name:t}),cleanup(){}};if(!r.allowBlobWorker)throw new Error("Cross-origin agent workers require allowBlobWorker=true or a same-origin workerUrl.");const o=new Blob([`import ${JSON.stringify(n.href)};
5
- `],{type:"text/javascript"}),i=URL.createObjectURL(o);try{return{worker:new Worker(i,{type:"module",name:t}),cleanup(){URL.revokeObjectURL(i)}}}catch(a){throw URL.revokeObjectURL(i),a}}function Ue(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function F(e){const t=Ue(e);if(!t)return null;const r=O(t.sku,t.SKU);if(!r)return null;const n={sku:r,name:O(t.name,t.title,t.short_name,r)||r,url:O(t.url)||""},o=Array.isArray(t.images)?t.images:void 0,i=O(t.imageUrl,t.image_url,t.image,o?.[0]);i&&(n.imageUrl=i),o&&o.length>1&&(n.images=o.filter(g=>!!g).map(String));const a=B(t.price_discounted),c=B(t.price),f=a||c;f>0&&(n.price=String(f));const m=a>0?c:0;m>0&&(n.originalPrice=String(m));const d=O(t.brand);d&&(n.brand=d);const s=B(t.rating);s>0&&(n.rating=s);const u=B(t.review_count)||B(t.reviewCount);u>0&&(n.reviewCount=u);const l=O(t.cart_code,t.cartCode);l&&(n.cartCode=l),typeof t.in_stock=="boolean"&&(n.inStock=t.in_stock),typeof t.inStock=="boolean"&&(n.inStock=t.inStock);const p=t.category_names;return Array.isArray(p)&&(n.categoryNames=p.map(String)),n}function Z(e){const t=Ue(e);if(!t)return e;const r=t.category_names,n=Array.isArray(r)?r:void 0,o=t.images,i=Array.isArray(o)?o:void 0,a={sku:t.sku,name:t.name||t.title,url:t.url,price:t.price,currency:t.price_currency||t.currency,category:n?.[n.length-1]??void 0,category_names:n?n.slice(0,4):void 0,image:i?i[0]:t.image,in_stock:t.in_stock,rating:t.rating,review_count:t.review_count};for(const c of Object.keys(a))a[c]===void 0&&delete a[c];return a}function gr(e){return Array.isArray(e)?e.map(Z).filter(t=>!!t):[]}function O(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function B(e){const t=Number(e);return Number.isFinite(t)?t:0}function Be(e){return Array.isArray(e)?e.map(String).filter(Boolean):typeof e=="string"&&e?[e]:[]}function hr(e=[]){const t={},r=[];return(Array.isArray(e)?e.map(F).filter(n=>!!n):[]).forEach((n,o)=>{const i=`product-${o.toString()}`;r.push(i);const a={sku:n.sku,product:n};t[i]={type:"ProductCard",props:{product:n,index:o,action:{title:n.name,type:"launchSingleProduct",payload:a}}}}),t.root={type:"ProductGrid",props:{layout:"grid"},children:r},{widget:"chat",panelHint:"panel",spec:{root:"root",elements:t}}}function wr(e){return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ProductDetailsPanel",props:{product:F(e)||e||{}}}}}}}function br(e={}){const t=(e.multiple_product_details||e.products||[]).map(F).filter(n=>!!n),r=e.table||{};return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ComparisonTable",props:{products:t,recommended:t.find(n=>n.sku===e.recommended_choice_sku)||t[0],attributes:Object.entries(r).map(([n,o])=>({label:n,values:Array.isArray(o)?o.map(String):[String(o??"")]})),highlights:Be(e.key_differences),specialCases:Be(e.special_considerations),recommendedText:e.recommended_choice,productActions:Object.fromEntries(t.map(n=>[n.sku,{title:n.name,type:"launchSingleProduct",payload:{sku:n.sku,product:n}}]))}}}}}}function Sr(e=[]){return{widget:"chat",panelHint:"inline",spec:{root:"root",elements:{root:{type:"ActionButtons",props:{buttons:(Array.isArray(e)?e:[]).map(t=>{const r=t.label||t.title||t.shortName||"",n=t.action||t.requestDetails||t.request_details;return!r||!n?.type?null:{label:r,action:{title:r,type:n.type,...n.payload!==void 0?{payload:n.payload}:{}}}}).filter(t=>!!t)}}}}}}function kr(e){return Object.freeze([...e])}var ve=new Set(["and","are","for","from","the","with"]),Ar={token:.26,keyword:.22,category:.18,facet:.16,color:.08,attribute:.06,price:.08,retrieval:.08},_r=["amber","beige","black","blue","blush","bronze","brown","cream","gold","green","grey","ivory","lilac","mixed","orange","pastel","pink","purple","red","silver","white","yellow"];function T(e){return String(e??"").normalize("NFKD").replace(new RegExp("\\p{Diacritic}","gu"),"").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function A(e,t=ve){const r=t instanceof Set?t:new Set([...ve,...t]),n=new Set,o=[];for(const i of T(e).split(/\s+/u))i.length<3||r.has(i)||n.has(i)||(n.add(i),o.push(i));return o}function v(e,t={}){if(Pr(e))return e;const r=t.facetKeys,n=S(e.category_names??e.category),o=S(e.category_ids),i=Ir(e.facet_hits),a=Object.entries(i).filter(([g])=>!r||r.some(h=>T(h)===T(g))).map(([,g])=>g),c=x(e.name,e.title),f=x(e.brand),m=t.sourceKeywords??[],d=[c,f,...n,...a,...S(e.promotions),x(e.description),...m].join(" "),s=A(d,t.stopWords),u=x(t.sourceProductType,Or(n,c,s),s[0]),l=P([...Cr(d,_r),...Object.entries(i).filter(([g])=>/colou?r/iu.test(g)).flatMap(([,g])=>A(g,t.stopWords))]),p=P([...a.flatMap(g=>A(g,t.stopWords)),...S(e.promotions).flatMap(g=>A(g,t.stopWords))]).slice(0,24);return{sku:x(e.sku),title:c,brand:f,productType:u,categoryNames:n,categoryIds:o,facets:i,keywords:P([...m.flatMap(g=>A(g,t.stopWords)),...s]).slice(0,12),tokens:s,colors:l,attributes:p,price:jr(e)}}function Er(e,t={}){const r=x(e.product_type,e.productType),n=x(e.title,r,S(e.keywords).join(" ")),o=P([...S(e.keywords),...S(e.colors),...S(e.materials),...S(e.styles),...S(e.attributes)]);return v({sku:"__photo__",name:n,category_names:r?[r]:[],facet_hits:{colors:S(e.colors).join(", "),materials:S(e.materials).join(", "),styles:S(e.styles).join(", "),attributes:S(e.attributes).join(", ")},promotions:o},{...t,sourceProductType:r,sourceKeywords:o})}function xr(e,t={}){const r=v(e,t);return P([...t.sourceQueries??[],q([r.productType,...r.colors.slice(0,1),...r.attributes.slice(0,2)]),q([r.productType,...r.keywords.slice(0,3)]),q([r.categoryNames[r.categoryNames.length-1],...r.keywords.slice(0,2)]),q(r.title.split(/\s+/u).slice(0,6)),r.productType].map(n=>n.trim()).filter(Boolean)).slice(0,t.queryLimit??6)}function Ne(e,t,r={}){const n={...Ar,...r.weights},o=v(t,r),i=[],a=R(e.tokens,o.tokens),c=R(e.keywords,o.tokens),f=Rr(e.categoryNames,o.categoryNames)||R(De(e.categoryNames),De(o.categoryNames)),m=R(e.attributes,o.attributes),d=R(e.colors,o.colors),s=R(e.attributes,o.tokens),u=Mr(e.price,o.price),l=Ur(o.sku,r.hitCounts)>0?1:0,p=Br(e,o),g=a*n.token+c*n.keyword+f*n.category+m*n.facet+d*n.color+s*n.attribute+u*n.price+l*n.retrieval,h=vr(p?g:g*.35);return p&&e.productType&&e.productType===o.productType&&i.push("same product type"),f>.4&&i.push("similar category"),m>.2&&i.push("matching product attributes"),d>0&&i.push("matching colour"),u>.8&&i.push("similar price"),p||i.push("weaker product-type match"),{score:Number(h.toFixed(4)),reasons:i}}function Tr(e,t,r={}){const n=v(e,r),o=new Set([n.sku,...r.ignoreSkus??[]].filter(Boolean));return t.filter(i=>{const a=x(i.sku);return a&&!o.has(a)}).map(i=>{const a=Ne(n,i,r);return{...i,similarity_score:a.score,similarity_reasons:a.reasons}}).sort((i,a)=>a.similarity_score-i.similarity_score).slice(0,Math.max(1,Math.min(r.limit??12,100)))}function Pr(e){return!!(e&&typeof e=="object"&&Array.isArray(e.tokens))}function x(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function S(e){return Array.isArray(e)?e.map(t=>x(t)).filter(Boolean):typeof e=="string"&&e.trim()?e.split(/[,;/|]+/u).map(t=>t.trim()).filter(Boolean):[]}function Ir(e){return!e||typeof e!="object"||Array.isArray(e)?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t,x(r)]).filter(([,t])=>t))}function jr(e){const t=Number(e.price_discounted);if(Number.isFinite(t)&&t>0)return t;const r=Number(e.price);return Number.isFinite(r)&&r>0?r:0}function P(e){const t=new Set,r=[];for(const n of e){const o=T(n);!o||t.has(o)||(t.add(o),r.push(o))}return r}function Cr(e,t){const r=` ${T(e)} `;return t.filter(n=>r.includes(` ${T(n)} `))}function Or(e,t,r){const n=T(e[e.length-1]??e[0]??"");if(n){const o=A(n),i=new Set(A(t));return o.find(a=>i.has(a))??o[0]??n}return r[0]??""}function q(e){return e.map(t=>T(t)).filter(Boolean).join(" ").replace(/\s+/gu," ").trim().slice(0,120)}function De(e){return e.flatMap(t=>A(t))}function R(e,t){const r=P(e),n=new Set(P(t));return r.length===0||n.size===0?0:r.filter(o=>n.has(o)).length/r.length}function Rr(e,t){const r=P(e),n=new Set(P(t));return r.length===0||n.size===0?0:r.filter(o=>n.has(o)).length/r.length}function Mr(e,t){return e<=0||t<=0?0:Math.min(e,t)/Math.max(e,t)}function Ur(e,t){return!e||!t?0:typeof t.get=="function"?t.get(e)??0:t[e]??0}function Br(e,t){if(!e.productType||!t.productType||e.productType===t.productType)return!0;const r=new Set(A(e.productType)),n=new Set([...A(t.productType),...t.tokens]);return[...r].some(o=>n.has(o))}function vr(e){return Math.max(0,Math.min(1,e))}function Nr(e){const t=(e?.chat||e?._chat)?.root||e?._chat?.root;return t?t.getRootNode?.()?.host||t:Array.from(document.querySelectorAll("*")).find(r=>r.shadowRoot?.querySelector?.(".gengage-chat-root, .gengage-chat-launcher-container"))}function Dr(e,t){const r=Nr(e);r?.style&&(t?r.style.removeProperty("display"):r.style.setProperty("display","none","important")),t||(e?.chat||e?._chat)?.close?.()}var Lr="nd_be_url";function $r(e,t){const r=Fr()||e.beUrl||t;if(!r)throw new Error("resolveBeUrl: backend URL is required. The injector must supply a fallback URL; the SDK has no default.");return r}function Fr(){try{const e=new URLSearchParams(window.location.search).get(Lr)?.trim();if(!e)return null;const t=new URL(e);return t.protocol!=="https:"&&t.protocol!=="http:"?null:t.toString().replace(/\/+$/u,"")}catch{return null}}function qr(e,t,r={}){return`${e}:${r.version||"v2"}:${K(t)}`}function Kr(e,t={}){return Le(e).map(r=>$e(typeof r=="string"?r:r.sku,t.locale)).filter(Boolean).filter((r,n,o)=>o.indexOf(r)===n).sort((r,n)=>ee(r,n,t.locale)).slice(0,t.limit||16).join(",")}function zr(e,t={}){return K(Le(e).map(r=>Gr(r,t)).filter(r=>!!r).sort((r,n)=>ee(String(r.sku||r.name||""),String(n.sku||n.name||""),t.locale)).slice(0,t.limit||16))}function Jr(e,t){return j(e,t)}function K(e){let t=2166136261;const r=Hr(e);for(let n=0;n<r.length;n+=1)t^=r.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function Gr(e,t){if(!e||typeof e!="object"||Array.isArray(e))return null;const r=e,n=t.mapProduct?.(r);if(n)return N(n);const o=Z(r);return o&&typeof o=="object"&&!Array.isArray(o)?N(Wr(o,t)):null}function Le(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"||!!(t&&typeof t=="object"&&!Array.isArray(t))):[]}function Hr(e){return JSON.stringify(N(e))}function N(e){return Array.isArray(e)?e.map(N):!e||typeof e!="object"?e:Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,N(r)]))}function Wr(e,t){return{sku:$e(e.sku,t.locale),name:j(e.name,t.locale),url:j(e.url,t.locale),price:e.price,currency:j(e.currency,t.locale),category:j(e.category,t.locale),category_names:Vr(e.category_names,t.locale,16),image:j(e.image,t.locale),in_stock:e.in_stock,rating:e.rating,review_count:e.review_count}}function $e(e,t){return j(e,t).toUpperCase()}function j(e,t){return typeof e=="string"?e.trim().replace(/\s+/gu," ").toLocaleLowerCase(t||void 0):""}function ee(e,t,r){return e.localeCompare(t,r,{numeric:!0})}function Vr(e,t,r){return Array.isArray(e)?e.map(n=>j(n,t)).filter(Boolean).sort((n,o)=>ee(n,o,t)).slice(0,r):void 0}var Yr="entries",Qr=1,Xr={volatile:"Hot per-page state and sensitive request context.",session:"Current-visit tool context without raw tokens or PII-heavy payloads.",local:"Small, non-sensitive capability facts or user preferences.",indexedDb:"Larger product/search payload caches with short TTLs."},Fe=new Map;function te(){return Date.now()}function re(e){return e?.expiresAt!=null&&e.expiresAt<=te()}function ne(e,t){return{value:e,createdAt:te(),expiresAt:t?te()+t:null}}function Zr(e,t,r){try{const n=e.getItem(`${t}${r}`);if(!n)return null;const o=JSON.parse(n);return re(o)?(e.removeItem(`${t}${r}`),null):o.value}catch{return null}}function en(e,t,r,n,o){try{return e.setItem(`${t}${r}`,JSON.stringify(ne(n,o))),!0}catch{return!1}}function tn(e,t,r){try{e.removeItem(`${t}${r}`)}catch{}}function qe(e){try{return window[e]}catch{return null}}function Ke(e,t){return e?{get:r=>Zr(e,t,r),set:(r,n,o={})=>en(e,t,r,n,o.ttlMs),remove:r=>tn(e,t,r)}:{get:()=>null,set:()=>!1,remove:()=>{}}}function rn(e,t){const r=t.dbName||`gengage-${e}`,n=t.dbStore||Yr,o=t.dbVersion||Qr,i=new Map;let a=null;const c=()=>"indexedDB"in window?a||(a=new Promise(s=>{const u=indexedDB.open(r,o);u.onupgradeneeded=()=>{u.result.createObjectStore(n,{keyPath:"key"})},u.onsuccess=()=>s(u.result),u.onerror=()=>s(null),u.onblocked=()=>s(null)}),a):Promise.resolve(null);return{volatileEntries:i,idbGet:async s=>{const u=await c();return u?new Promise(l=>{const p=u.transaction(n,"readwrite").objectStore(n),g=p.get(s);g.onsuccess=()=>{const h=g.result;if(!h||re(h)){h&&p.delete(s),l(null);return}l(h.value)},g.onerror=()=>l(null)}):null},idbSet:async(s,u,l={})=>{const p=await c();return p?new Promise(g=>{const h=p.transaction(n,"readwrite");h.oncomplete=()=>g(!0),h.onerror=()=>g(!1),h.objectStore(n).put({key:s,...ne(u,l.ttlMs)})}):!1},idbRemove:async s=>{const u=await c();u&&u.transaction(n,"readwrite").objectStore(n).delete(s)}}}function nn(e,t={}){const r=window,n=r.gengage||(r.gengage={}),o=n.memory||(n.memory={}),i=o[e];if(i)return i;const a=Fe.get(e)||rn(e,t);Fe.set(e,a);const c=t.sessionPrefix||`gengage:${e}:session:`,f=t.localPrefix||`gengage:${e}:local:`,d={get:l=>{const p=a.volatileEntries.get(l);return p?re(p)?(a.volatileEntries.delete(l),null):p.value:null},set:(l,p,g={})=>(a.volatileEntries.set(l,ne(p,g.ttlMs)),!0),remove:l=>{a.volatileEntries.delete(l)},clear:()=>a.volatileEntries.clear()},s={get:a.idbGet,set:a.idbSet,remove:a.idbRemove},u={accountId:e,volatile:d,session:Ke(qe("sessionStorage"),c),local:Ke(qe("localStorage"),f),indexedDb:s,stableKey:K,policy:{...Xr,...t.policy||{}}};o[e]=u;for(const l of t.aliases||[])o[l]=u;return u}var on=["addToCart","search","searchKeyword","facetedSearch","searchGiftOptions","similaritySearch"];function an(e,t,r={}){const n=window,o=n.gengage||(n.gengage={}),i=o.tools||(o.tools={});i[e]=t;for(const a of r.accountAliases||[])i[a]=t;if(r.exposeStandardAliases!==!1)for(const a of r.standardAliases||on){const c=t[a];typeof c=="function"&&(i[a]=i[a]||c)}return t}function cn({getPageType:e,getProduct:t}){return()=>({url:window.location.href,title:document.title,pageType:e(),product:t()})}function sn({accountId:e,getPageType:t,getProduct:r,getToolNames:n,getSearchCapabilities:o,getMemory:i}){return async()=>({accountId:e,url:window.location.href,pageType:t(),productSku:r()?.sku??null,toolNames:n(),...o?{searchCapabilities:o()}:{},...i?{memoryPolicy:i().policy}:{},timestamp:new Date().toISOString()})}function un({accountId:e,runtimeFile:t="runtime.js",startExport:r="start",globalBaseUrlKey:n,errorLabel:o}={}){if(!e)throw new Error("accountId is required.");const i=o||e,a=window,c=()=>{const s=a.GengageInjectorConfig||{},u=s[e]||{};return{...s,...u}},f=()=>{const s=c();if(s.runtimeUrl)return s.runtimeUrl;const u=s.assetBaseUrl||s.baseUrl||document.currentScript?.getAttribute("src")||(n?a[n]:null);if(!u)throw new Error(`${i} runtime URL cannot be resolved.`);return new URL(t,u).href},m=a.GengageAssistantInjector||(a.GengageAssistantInjector={}),d=m[e]||(m[e]={});return d.loaderPromise||(d.loaderPromise=import(f()).then(s=>{const u=s[r];if(typeof u!="function")throw new Error(`${i} runtime export ${r} is unavailable.`);return u()}).catch(s=>{throw delete d.loaderPromise,console.error(`[Gengage][${e}] runtime load failed`,s),s})),d.loaderPromise}function ln(e){const t=e?.payload;if(typeof t=="string")return t;if(t&&typeof t=="object"&&"text"in t){const n=t.text;if(typeof n=="string")return n}const r=e?.action;return r&&typeof r.payload=="string"?r.payload:r&&typeof r.title=="string"?r.title:""}y.AgentError=D,y.ContextStore=ue,y.action=vt,y.actionButtonsUiSpec=Sr,y.beErrorToAgentError=z,y.buildPhotoSimilarityProfile=Er,y.buildProductSimilarityProfile=v,y.buildSimilarityQueries=xr,y.canUseModuleWorker=X,y.caughtToStreamError=ge,y.comparisonUiSpec=br,y.createBrowserMemory=nn,y.createDiagnosticsTool=sn,y.createFlow=kr,y.createInjectorAdapter=Te,y.createMainThreadInjectorAdapter=Pe,y.createModuleWorker=Me,y.createReadPageTool=cn,y.done=H,y.elapsedMs=C,y.error=Ae,y.httpErrorToAgentError=pe,y.installBrowserTools=an,y.installFetchTransportBridge=cr,y.llmCacheKey=qr,y.metadata=Ut,y.mountAccount=pr,y.normalizeProduct=F,y.normalizeSimilarityText=T,y.nowIso=ae,y.productDetailsUiSpec=wr,y.productFactsKey=zr,y.productSkuKey=Kr,y.productsUiSpec=hr,y.rankSimilarProducts=Tr,y.requestText=ln,y.resolveBeUrl=$r,y.resolveFlow=_e,y.scoreSimilarityCandidate=Ne,y.setAssistantHostVisible=Dr,y.stableKey=K,y.startLazyRuntimeLoader=un,y.textChunk=ke,y.textKey=Jr,y.tokenizeSimilarityText=A,y.trimProductFactsCore=Z,y.trimProductFactsListCore=gr,y.uiSpec=Bt})(this.Gengage=this.Gengage||{});
1
+ (function(p){Object.defineProperty(p,Symbol.toStringTag,{value:"Module"});function Qe(e){return!!e&&typeof e=="object"&&e.type==="rpc.req"}function Xe({worker:e,tools:t={},beacon:r,memory:n=sessionStorage}){e.addEventListener("message",o=>{const i=o.data;Qe(i)&&Ze(e,i,{tools:t,beacon:r,memory:n})})}async function Ze(e,t,r){try{const n=await ce(t.method,t.payload,r);e.postMessage({type:"rpc.result",rpcId:t.rpcId,ok:!0,value:n})}catch(n){e.postMessage({type:"rpc.result",rpcId:t.rpcId,ok:!1,error:{message:n instanceof Error?n.message:String(n)}})}}function et(e){if(e&&typeof e=="object"&&typeof e.name=="string")return e;throw new Error("tool.invoke requires { name, input }")}function tt(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.get requires { key }")}function rt(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.set requires { key }")}async function ce(e,t,{tools:r,beacon:n,memory:o}){if(e==="tool.invoke"){const{name:i,input:a}=et(t),c=r[i];if(typeof c!="function")throw new Error(`Unknown tool: ${i}`);return c(a)}if(e==="beacon.send")return n?.(t),{sent:!0};if(e==="memory.get"){const{key:i}=tt(t),a=o.getItem(String(i));return a?JSON.parse(a):null}if(e==="memory.set"){const{key:i,value:a}=rt(t);return o.setItem(String(i),JSON.stringify(a??null)),{ok:!0}}throw new Error(`Unknown RPC method: ${e}`)}function se(){return new Date().toISOString()}function j(e){return Math.max(0,Math.round(performance.now()-e))}function U(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function nt(e){const{accountId:t,locale:r="en-GB",parentUrl:n="",threadId:o,incomingContext:i}=e,a=U(i)?i:{},c=U(a.thread)?a.thread:{},y=U(a.panel)?a.panel:{},f=U(a.meta)?a.meta:{},d=ue(a.messages),s={id:String(o||c.id||self.crypto.randomUUID()),started_at:String(c.started_at||se()),extensions:U(c.extensions)?{...c.extensions}:{}},u=String(f.locale||r),l=String(f.parentUrl||n||typeof self<"u"&&self.location?.href||"");return{panel:{...y},messages:d,thread:s,meta:{locale:u,parentUrl:l,accountId:t}}}function ot(e,t){const r=ue([t])[0];return r?{...e,messages:[...e.messages,r].slice(-50)}:e}function ue(e){return Array.isArray(e)?e.map(t=>{const r=t?.role;return{role:r==="model"?"assistant":typeof r=="string"?r:"",content:String(t?.content||"")}}).filter(t=>(t.role==="user"||t.role==="assistant")&&!!t.content).slice(-50):[]}var it="gengage:agent:context:";async function at({accountId:e,threadId:t,rpc:r}){const n=await r("memory.get",{tier:"session",key:le(e,t)});return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}async function ct({accountId:e,threadId:t,extensions:r,panel:n,rpc:o}){await o("memory.set",{tier:"session",key:le(e,t),value:{thread:{extensions:r},...n&&Object.keys(n).length>0?{panel:n}:{}}})}function le(e,t){return`${it}${e}:${t}`}function b(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var de=class{#e=new Map;#t;#n;#o;#r;#i;constructor({accountId:e,locale:t,parentUrl:r,rpc:n,persistentPanelKeys:o=[]}){this.#t=e,this.#n=t,this.#o=r,this.#r=n,this.#i=[...new Set(o.filter(Boolean))]}async load(e){const t=e?.meta?.threadId||e?.session_id||e?.sessionId,r=String(t||"default"),n=this.#e.get(r);if(n)return n;const o=await at({accountId:this.#t,threadId:r,rpc:this.#r}),i=nt({accountId:this.#t,locale:e?.locale||this.#n,parentUrl:this.#o,threadId:r,incomingContext:ut(o,e?.context)});return this.#e.set(r,i),i}patch(e,t){const r=String(e||"default"),n=this.#e.get(r);if(!n)return null;const o=fe(n,typeof t=="function"?t(n):t);return this.#e.set(r,o),o}appendUserMessage(e,t){const r=String(e||"default");if(!t)return this.#e.get(r)??null;const n=this.#e.get(r);if(!n)return null;const o=ot(n,{role:"user",content:t});return this.#e.set(r,o),o}async commit(e){const t=String(e||"default"),r=this.#e.get(t);return r?(await ct({accountId:this.#t,threadId:t,extensions:r.thread.extensions,panel:st(r.panel,this.#i),rpc:this.#r}),r):null}};function st(e,t){if(!t.length||!b(e))return;const r={};for(const n of t)Object.prototype.hasOwnProperty.call(e,n)&&(r[n]=e[n]);return r}function ut(e,t){return!b(e)&&!b(t)?{}:fe(b(e)?e:{},b(t)?t:{})}function fe(e,t){if(!b(t))return e;const r=e,n=t,o=b(r.panel)?r.panel:{},i=b(n.panel)?n.panel:{},a=b(r.thread)?r.thread:{},c=b(n.thread)?n.thread:{},y=b(a.extensions)?a.extensions:{},f=b(c.extensions)?c.extensions:{},d=b(r.meta)?r.meta:{},s=b(n.meta)?n.meta:{};return{...e,...t,panel:{...o,...i},thread:{...a,...c,extensions:{...y,...f}},meta:{...d,...s},messages:Array.isArray(n.messages)?n.messages.slice(-50):e.messages??[]}}function ye(e){const t=String.fromCharCode(...e);return btoa(t).replace(/\+/gu,"-").replace(/\//gu,"_").replace(/=+$/u,"")}function me(e){return ye(new TextEncoder().encode(JSON.stringify(e)))}async function lt({accountId:e,devJwtSecret:t,ttlS:r=300}){if(!t)throw new Error("devJwtSecret is required for local agent mode.");const n=Math.floor(Date.now()/1e3),o=`${me({alg:"HS256",typ:"JWT"})}.${me({sub:e,iat:n,exp:n+r,scope:"invoke",jti:crypto.randomUUID?.()||`${n}-${Math.random()}`})}`,i=await crypto.subtle.importKey("raw",new TextEncoder().encode(t),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),a=await crypto.subtle.sign("HMAC",i,new TextEncoder().encode(o));return`${o}.${ye(new Uint8Array(a))}`}function J({accountId:e,devJwtSecret:t,tokenBrokerUrl:r,tokenBrokerAudience:n,refreshSkewS:o=30,fetchImpl:i=fetch}){let a=null;return async({signal:c,parentUrl:y}={})=>{if(t)return lt({accountId:e,devJwtSecret:t});if(!r)throw new Error("tokenBrokerUrl is required for production agent mode.");const f=Math.floor(Date.now()/1e3);return a?.token&&a.expiresAtS-o>f||(a=await dt({accountId:e,tokenBrokerUrl:r,tokenBrokerAudience:n,parentUrl:y,signal:c,fetchImpl:i})),a.token}}async function dt({accountId:e,tokenBrokerUrl:t,tokenBrokerAudience:r,parentUrl:n,signal:o,fetchImpl:i}){const a=await i(t,{method:"POST",credentials:"include",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({accountId:e,scope:"invoke",audience:r||void 0,parentUrl:n||void 0}),...o?{signal:o}:{}});if(!a.ok)throw new Error(`Token broker request failed (${a.status}).`);const c=await a.json(),y=c?.token||c?.jwt||c?.access_token;if(!y||typeof y!="string")throw new Error("Token broker response did not include a JWT.");return{token:y,expiresAtS:ft(c)||yt(y)||Math.floor(Date.now()/1e3)+300}}function ft(e){const t=e?.expiresAtS??e?.expires_at_s??e?.expiresInS??e?.expires_in_s;if(Number.isFinite(t))return Number(t);const r=e?.expiresIn??e?.expires_in;if(Number.isFinite(r))return Math.floor(Date.now()/1e3)+Number(r);const n=e?.expiresAt??e?.expires_at;if(typeof n=="string"){const o=Date.parse(n);if(Number.isFinite(o))return Math.floor(o/1e3)}return null}function yt(e){try{const[,t]=e.split(".");if(!t)return null;const r=t.replace(/-/gu,"+").replace(/_/gu,"/"),n=atob(r.padEnd(Math.ceil(r.length/4)*4,"=")),o=JSON.parse(n);return Number.isFinite(o?.exp)?Number(o.exp):null}catch{return null}}var pe={unauthorized:{code:"auth",message:"Assistant authentication failed. Please retry."},forbidden:{code:"auth",message:"Assistant authentication failed. Please retry."},unknown_op:{code:"op_unavailable",message:"This assistant action is not available yet."},invalid_input:{code:"invalid_request",message:"The assistant request was not valid."},account_config:{code:"account_config",message:"Assistant configuration is unavailable."},upstream_llm:{code:"op_failed",message:"The assistant could not complete that request."},upstream_timeout:{code:"op_timeout",message:"The assistant took too long to respond."},schema_mismatch:{code:"op_failed",message:"The assistant could not complete that request."},rate_limited:{code:"rate_limited",message:"The assistant is receiving too many requests. Please retry shortly."},internal:{code:"op_failed",message:"The assistant could not complete that request."},payload_too_large:{code:"invalid_request",message:"The assistant request was too large."}},L=class extends Error{constructor(e,t,r={}){super(t),this.name="AgentError",this.code=e,this.source=r.source||"agent",r.sourceCode&&(this.sourceCode=r.sourceCode),r.detail!==void 0&&(this.detail=r.detail)}};function z(e){const t=String(e?.code||"upstream_llm"),r=pe[t]||pe.upstream_llm;return new L(r.code,r.message,{source:"be",sourceCode:t,detail:e?.detail})}function ge(e,t){const r=t?.error&&typeof t.error=="object"?t.error:{};return z({code:String(r.code||mt(e)),detail:r.detail})}function he(e){return e instanceof L?{type:"error",code:e.code,message:e.message}:{type:"error",code:"agent_invoke_failed",message:"The assistant could not complete that request."}}function mt(e){return e===401?"unauthorized":e===403?"forbidden":e===413?"payload_too_large":e===429?"rate_limited":"internal"}var pt=7200*1e3,we=200,gt=5*1024*1024,ht="gengage_request_response_cache",wt=1,_="responses",bt=new Set(["addToCart","like"]),E=new Map,be=null;async function St(e,t={},r={}){const n=kt(e,t);if(!n)return fetch(e,t);const o=Date.now(),i=await _t(n,o);if(i)return Tt(i);const a=await fetch(e,t);return a.ok&&Et(n,a.clone(),o,{ttlMs:r.ttlMs??pt,maxEntries:r.maxEntries??we,maxBodyBytes:r.maxBodyBytes??gt}),a}function kt(e,t={}){if(typeof Request<"u"&&e instanceof Request)return null;const r=String(t.method||"GET").toUpperCase();return r!=="POST"||typeof t.body!="string"||At(t.body)?null:`rr:${Ut(Rt({url:String(e),method:r,headers:Pt(t.headers),body:t.body}))}`}function At(e){try{const t=JSON.parse(e);if(!t||typeof t!="object"||Array.isArray(t))return!1;const r=t.type;return typeof r=="string"&&bt.has(r)}catch{return!1}}async function _t(e,t){const r=E.get(e);if(r)if(r.expiresAt<=t)E.delete(e);else return r.lastAccessedAt=t,E.delete(e),E.set(e,r),H(r),r;const n=await Ct(e);return n?n.expiresAt<=t?(E.delete(e),jt(e),null):(n.lastAccessedAt=t,E.set(e,n),H(n),Se(we),n):null}async function Et(e,t,r,n){try{const o=await t.text();if(Mt(o)>n.maxBodyBytes||xt(o))return;const i={key:e,status:t.status,statusText:t.statusText,headers:It(t.headers),body:o,createdAt:r,expiresAt:r+n.ttlMs,lastAccessedAt:r};E.set(e,i),Se(n.maxEntries),await H(i),await Ot(n.maxEntries,r)}catch{}}function xt(e){return/"_error"\s*:/u.test(e)||/"type"\s*:\s*"error"/u.test(e)}function Tt(e){return new Response(e.body,{status:e.status,statusText:e.statusText,headers:new Headers(e.headers)})}function Pt(e){const t=new Headers(e),r=[];return t.forEach((n,o)=>{const i=o.toLowerCase();i!=="authorization"&&i!=="cookie"&&r.push([i,n])}),r.sort(([n],[o])=>n.localeCompare(o))}function It(e){const t=[];return e.forEach((r,n)=>{const o=n.toLowerCase();o!=="set-cookie"&&t.push([o,r])}),t.sort(([r],[n])=>r.localeCompare(n))}function Se(e){for(;E.size>e;){const t=[...E.values()].sort((r,n)=>r.lastAccessedAt-n.lastAccessedAt)[0];if(!t)break;E.delete(t.key)}}async function $(){return typeof indexedDB>"u"?null:(be??=new Promise(e=>{const t=indexedDB.open(ht,wt);t.onupgradeneeded=()=>{const r=t.result;r.objectStoreNames.contains(_)||r.createObjectStore(_,{keyPath:"key"}).createIndex("lastAccessedAt","lastAccessedAt",{unique:!1})},t.onsuccess=()=>e(t.result),t.onerror=()=>e(null),t.onblocked=()=>e(null)}),be)}async function Ct(e){const t=await $();return t?new Promise(r=>{const n=t.transaction(_,"readonly"),o=n.objectStore(_).get(e);o.onsuccess=()=>r(o.result??null),o.onerror=()=>r(null),n.onerror=()=>r(null)}):null}async function H(e){const t=await $();t&&await new Promise(r=>{const n=t.transaction(_,"readwrite");n.objectStore(_).put(e),n.oncomplete=()=>r(),n.onerror=()=>r(),n.onabort=()=>r()})}async function jt(e){const t=await $();t&&await new Promise(r=>{const n=t.transaction(_,"readwrite");n.objectStore(_).delete(e),n.oncomplete=()=>r(),n.onerror=()=>r(),n.onabort=()=>r()})}async function Ot(e,t){const r=await $();r&&await new Promise(n=>{const o=r.transaction(_,"readwrite"),i=o.objectStore(_),a=[],c=i.openCursor();c.onsuccess=()=>{const y=c.result;if(!y){const f=a.filter(s=>s.expiresAt<=t),d=a.filter(s=>s.expiresAt>t).sort((s,u)=>s.lastAccessedAt-u.lastAccessedAt).slice(0,Math.max(0,a.length-f.length-e));for(const s of[...f,...d])i.delete(s.key);return}a.push(y.value),y.continue()},c.onerror=()=>n(),o.oncomplete=()=>n(),o.onerror=()=>n(),o.onabort=()=>n()})}function Rt(e){return JSON.stringify(G(e))}function G(e){return Array.isArray(e)?e.map(G):!e||typeof e!="object"?e:Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,G(r)]))}function Ut(e){let t=14695981039346656037n;const r=1099511628211n;for(let n=0;n<e.length;n+=1)t^=BigInt(e.charCodeAt(n)),t=BigInt.asUintN(64,t*r);return t.toString(16).padStart(16,"0")}function Mt(e){return typeof TextEncoder<"u"?new TextEncoder().encode(e).byteLength:e.length}async function Bt({beUrl:e,accountId:t,devJwtSecret:r,tokenBrokerUrl:n,tokenBrokerAudience:o,jwtProvider:i,parentUrl:a,op:c,input:y,cacheTtlS:f,cacheKey:d,browserCache:s,signal:u}){const l=await(i||J({accountId:t,devJwtSecret:r,tokenBrokerUrl:n,tokenBrokerAudience:o}))({...u?{signal:u}:{},...a?{parentUrl:a}:{}}),{opDomain:m,opName:g}=vt(c,t),h={method:"POST",headers:{authorization:`Bearer ${l}`,"content-type":"application/json",accept:"application/x-ndjson"},body:JSON.stringify({op_domain:m,op_name:g,op_payload:y,...f!==void 0?{cache_ttl_s:f}:{},...d!==void 0?{cache_key:d}:{}}),...u?{signal:u}:{}},k=`${String(e).replace(/\/+$/u,"")}/v1/execute`,w=s===!1?await fetch(k,h):await St(k,h,typeof s=="object"?s:{});if(!w.ok)throw ge(w.status,await Dt(w));return Lt(w)}function vt(e,t){if(!e||e.startsWith("-")||e.endsWith("-"))throw new Error(`Invalid BE op name: ${e}`);return{opDomain:Nt(t),opName:e}}function Nt(e){return e.replace(/-agentic$/u,"")}async function Dt(e){try{return await e.json()}catch{return{error:{code:e.statusText||"internal"}}}}async function Lt(e){const t=e.body?.getReader();if(!t)throw new Error("BE response body is not readable.");const r=new TextDecoder;let n="";const o={};for(;;){const{value:a,done:c}=await t.read();if(c)break;n+=r.decode(a,{stream:!0});let y=n.indexOf(`
2
+ `);for(;y>=0;){const f=n.slice(0,y).trim();n=n.slice(y+1),f&&ke(JSON.parse(f),o),y=n.indexOf(`
3
+ `)}}const i=n.trim();return i&&ke(JSON.parse(i),o),o}function ke(e,t){if(e._error)throw z(e._error);if(!e._end)for(const[r,n]of Object.entries(e)){if(Object.prototype.hasOwnProperty.call(t,r))throw new L("op_failed",`BE streamed duplicate field "${r}".`,{source:"be",sourceCode:"schema_mismatch"});t[r]=n}}function $t(e={}){return{type:"metadata",...e}}function Ae(e,t=!1,r={}){return{type:"text_chunk",content:e,final:t,...r}}function Ft(e){return{type:"ui_spec",...e}}function qt(e){return{type:"action",action:e}}function _e(e,t){return{type:"error",code:e,message:t}}function W(){return{type:"done"}}function Ee(e,t){return e[t?.type||t?.action?.type||"inputText"]||e.inputText}async function Kt({request:e,accountModule:t,contextStore:r,beClient:n,toolBridge:o,emit:i,rpc:a,signal:c}){const y=performance.now(),f=await r.load(e),d=f.thread.id,s=rr(e);r.appendUserMessage(d,s);const u=Ee(t.flows,e);if(!u)return i(_e("unknown_action",`No agent flow for request type ${e?.type||"inputText"}`)),i(W()),{steps:0,productSkusEmitted:[]};const l={request:e,context:r.patch(d,{})||f,bag:{},accountConfig:t.accountConfig||{},threadId:d,steps:0,productSkusEmitted:new Set,committed:!1},m={contextStore:r,beClient:n,toolBridge:o,emit:i,rpc:a,adapters:t.adapters||{},...c?{signal:c}:{}};return await M(u,l,m),l.committed||await V(l,m),await a("beacon.send",{type:"turnSummary",threadId:d,sessionId:e?.session_id||e?.sessionId||d,accountId:t.accountId||l.context.meta.accountId,steps:l.steps,totalLatencyMs:j(y),productSkusEmitted:[...l.productSkusEmitted]}),{steps:l.steps,productSkusEmitted:[...l.productSkusEmitted]}}async function M(e,t,r){for(const n of e){if(r.signal?.aborted)return;t.steps+=1,await Jt(n,t,r),t.context=r.contextStore.patch(t.threadId,{})||t.context}}async function Jt(e,t,r){const n=Q(t);if(e.kind==="be_op"){await zt(e,t,r,n);return}if(e.kind==="tool"){await Ht(e,t,r,n);return}if(e.kind==="adapter"){await Gt(e,t,r,n);return}if(e.kind==="emit"){Wt(e,t,r);return}if(e.kind==="branch"){await Vt(e,t,r,n);return}if(e.kind==="parallel"){await Yt(e,t,r);return}if(e.kind==="refusal"){await Qt(e,t,r,n);return}e.kind==="commit"&&await Xt(e,t,r)}async function zt(e,t,r,n){const o=performance.now();let i;const a=I(e.cacheTtlS,n),c=I(e.cacheKey,n),y=I(e.browserCache,n);try{i=await r.beClient.invoke({op:e.op,input:I(e.input,n),...a!==void 0?{cacheTtlS:a}:{},...c!==void 0?{cacheKey:c}:{},...y!==void 0?{browserCache:y}:{},...r.signal?{signal:r.signal}:{}})}catch(d){const s=d,u=String(s?.sourceCode||s?.code||"unknown"),l={type:"agentOp",threadId:t.threadId,sessionId:t.request?.session_id||t.request?.sessionId||t.threadId,accountId:t.context.meta.accountId,op:e.op,status:"error",latencyMs:j(o),errorCode:u};if(await r.rpc("beacon.send",l),e.onError){e.errorOut&&(t.bag[e.errorOut]=d),await M(e.onError,t,r);return}throw d}e.out&&(t.bag[e.out]=i),Y(e,i,t,r.contextStore);const f={type:"agentOp",threadId:t.threadId,sessionId:t.request?.session_id||t.request?.sessionId||t.threadId,accountId:t.context.meta.accountId,op:e.op,status:"ok",latencyMs:j(o)};await r.rpc("beacon.send",f)}async function Ht(e,t,r,n){const o=performance.now();try{const i=await r.toolBridge.invoke(e.name,I(e.input,n));e.out&&(t.bag[e.out]=i),Y(e,i,t,r.contextStore),await r.rpc("beacon.send",{type:"agentTool",threadId:t.threadId,sessionId:xe(t),accountId:t.context.meta.accountId,tool:e.name,status:"ok",latencyMs:j(o)})}catch(i){const a=i;if(await r.rpc("beacon.send",{type:"agentTool",threadId:t.threadId,sessionId:xe(t),accountId:t.context.meta.accountId,tool:e.name,status:"error",latencyMs:j(o),errorCode:String(a?.code||a?.name||"unknown")}),e.onError){e.errorOut&&(t.bag[e.errorOut]=i),await M(e.onError,t,r);return}throw i}}async function Gt(e,t,r,n){const o=r.adapters?.[e.name];if(typeof o!="function")throw new Error(`Unknown flow adapter: ${e.name}`);const i=await o(I(e.input,n),n);e.out&&(t.bag[e.out]=i),Y(e,i,t,r.contextStore)}function Wt(e,t,r){const n=e.build(Q(t));nr(n,t.productSkusEmitted),r.emit(n)}async function Vt(e,t,r,n){const o=String(I(e.on,n)||"default");await M(e.cases[o]||e.cases.default||[],t,r)}async function Yt(e,t,r){const n=e.steps.map(a=>{const c={...t,context:Zt(t.context),bag:{...t.bag},productSkusEmitted:t.productSkusEmitted,committed:!1};return M(a,c,{...r,contextStore:er(c)}).then(()=>c)}),o=await Promise.all(n),i=e.merge||{};for(const a of o){for(const c of i.bag||[])Object.prototype.hasOwnProperty.call(a.bag,c)&&(t.bag[c]=a.bag[c]);if(i.panel?.length){const c=Te(a.context.panel,i.panel);Object.keys(c).length&&(t.context=r.contextStore.patch(t.threadId,{panel:c})||t.context)}if(i.threadExtensions?.length){const c=Te(a.context.thread.extensions,i.threadExtensions);Object.keys(c).length&&(t.context=r.contextStore.patch(t.threadId,{thread:{...t.context.thread,extensions:c}})||t.context)}}}async function Qt(e,t,r,n){r.emit(Ae(I(e.message,n),!0)),await V(t,r)}async function Xt(e,t,r){await V(t,r)}async function V(e,{contextStore:t,emit:r}){e.committed||(e.context=await t.commit(e.threadId)||e.context,e.committed=!0,r(W()))}function Y(e,t,r,n){if(typeof e.patch!="function")return;const o=e.patch(r.context,t,Q(r));o&&(r.context=n.patch(r.threadId,o)||r.context)}function Q(e){return{request:e.request,context:e.context,bag:e.bag,accountConfig:e.accountConfig}}function xe(e){return e.request?.session_id||e.request?.sessionId||e.threadId}function Zt(e){return typeof structuredClone=="function"?structuredClone(e):JSON.parse(JSON.stringify(e))}function Te(e,t){const r={};for(const n of t)Object.prototype.hasOwnProperty.call(e,n)&&(r[n]=e[n]);return r}function er(e){return{async load(){return e.context},patch(t,r){return e.context=tr(e.context,r),e.context},appendUserMessage(){return e.context},async commit(){return e.context}}}function tr(e,t){return!t||typeof t!="object"?e:{...e,...t,panel:{...e.panel||{},...t.panel||{}},thread:{...e.thread||{},...t.thread||{},extensions:{...e.thread?.extensions||{},...t.thread?.extensions||{}}},meta:{...e.meta||{},...t.meta||{}},messages:Array.isArray(t.messages)?t.messages.slice(-50):e.messages}}function I(e,t){return typeof e=="function"?e(t):e}function rr(e){const t=e?.payload;if(typeof t=="string")return t;if(t&&typeof t=="object"&&"text"in t){const r=t.text;if(typeof r=="string")return r}return typeof e?.action?.payload=="string"?e.action.payload:typeof e?.action?.title=="string"?e.action.title:""}function nr(e,t){const r=e,n=r.spec,o=Array.isArray(n?.items)?n.items:void 0,i=Array.isArray(r.items)?r.items:void 0,a=o||i;if(Array.isArray(a)){for(const c of a)if(c&&typeof c=="object"){const y=c.sku;typeof y=="string"&&t.add(y)}}}function or(e){return{invoke(t,r){return e("tool.invoke",{name:t,input:r})}}}var ir=512,ar=.74;function Pe({accountId:e,worker:t,beUrl:r,devJwtSecret:n,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,tools:c={},beacon:y}){let f=1;const d=new Map;return Xe({worker:t,tools:c,beacon:s=>y?.({...s,accountId:s.accountId||e}),memory:sessionStorage}),t.addEventListener("message",s=>{const u=s.data||{},l=typeof u.id=="number"?u.id:null;if(l==null)return;const m=d.get(l);if(m){if(u.type==="event"&&u.event){X(m,u.event);return}if(u.type==="error"){m.onError(new Error(u.message||"Agent worker failed")),d.delete(l);return}u.type==="end"&&d.delete(l)}}),(s,u,l,m)=>{const g=f++;d.set(g,u);const h=()=>{d.delete(g),t.postMessage({id:g,type:"abort"})},k=w=>{if(l.aborted){h();return}t.postMessage({id:g,type:"invoke",accountId:e,beUrl:r,devJwtSecret:n,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,request:w,parentUrl:window.location.href})};if(l.aborted){h();return}if(l.addEventListener("abort",h,{once:!0}),m){Ce(s,m).then(k).catch(w=>{d.delete(g),u.onError(w instanceof Error?w:new Error("Failed to read image attachment"))});return}k(s)}}function Ie({accountId:e,accountModule:t,beUrl:r,devJwtSecret:n,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,tools:c={},beacon:y}){let f=null;const d=cr({accountId:e,tools:c,beacon:y}),s=or(d),u=J({accountId:e,...n?{devJwtSecret:n}:{},...o?{tokenBrokerUrl:o}:{},...i?{tokenBrokerAudience:i}:{}});return async(l,m,g,h)=>{const k=await Ce(l||{},h);f||=new de({accountId:e,locale:k?.locale||a,parentUrl:window.location.href,rpc:d,persistentPanelKeys:t.contextPersistence?.panelKeys});try{await Kt({request:k,accountModule:{...t,accountId:e},contextStore:f,beClient:{invoke({op:w,input:ae,signal:Ye,cacheTtlS:Cn,cacheKey:jn,browserCache:On}){return Bt({beUrl:r,accountId:e,jwtProvider:u,parentUrl:window.location.href,op:w,input:ae,cacheTtlS:Cn,cacheKey:jn,browserCache:On,...Ye?{signal:Ye}:{}})}},toolBridge:s,emit:w=>X(m,w),rpc:d,signal:g})}catch(w){g?.aborted||(X(m,he(w)),m.onDone())}}}function cr({accountId:e,tools:t,beacon:r}){const n=o=>r?.({...o,accountId:o.accountId||e});return((o,i)=>ce(o,i,{tools:t,beacon:n,memory:sessionStorage}))}async function Ce(e,t){if(!t||!t.type?.startsWith("image/"))return e;const r=await lr(t),n={...sr(e.payload??e.action?.payload),image_data_url:r.dataUrl,image_mime:r.mime};return{...e,payload:n,...e.action?{action:{...e.action,payload:n}}:{}}}function sr(e){return ur(e)?{...e}:typeof e=="string"?{text:e}:{}}function ur(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function lr(e){const t=await dr(e);return t||{dataUrl:await je(e),mime:e.type}}async function dr(e){if(typeof createImageBitmap!="function"||typeof document>"u")return null;let t=null;try{t=await createImageBitmap(e);const r=Math.min(1,ir/Math.max(t.width,t.height)),n=Math.max(1,Math.round(t.width*r)),o=Math.max(1,Math.round(t.height*r)),i=document.createElement("canvas");i.width=n,i.height=o;const a=i.getContext("2d");if(!a)return null;a.drawImage(t,0,0,n,o);const c=await new Promise(y=>i.toBlob(y,"image/jpeg",ar));return c?{dataUrl:await je(c),mime:c.type||"image/jpeg"}:null}catch{return null}finally{t?.close()}}async function je(e){const t=new Uint8Array(await e.arrayBuffer());let r="";const n=32768;for(let o=0;o<t.length;o+=n)r+=String.fromCharCode(...t.subarray(o,o+n));return`data:${e.type};base64,${btoa(r)}`}function X(e,t){switch(t?.type){case"text_chunk":{const r=t;e.onTextChunk(r.content||"",r.final===!0,r);break}case"ui_spec":{const r=t;e.onUISpec(r.spec,r.widget,r.panelHint,r.clearPanel===!0);break}case"action":e.onAction(t);break;case"metadata":e.onMetadata(t);break;case"error":e.onError(fr(t));break;case"done":e.onDone();break;default:break}}function fr(e){const t=new Error(e.message||e.code||"Agent error");return e.code&&(t.code=e.code),t}function Oe(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function F(e){const t=Oe(e);if(!t)return null;const r=O(t.sku,t.SKU);if(!r)return null;const n={sku:r,name:O(t.name,t.title,t.short_name,r)||r,url:O(t.url)||""},o=Array.isArray(t.images)?t.images:void 0,i=O(t.imageUrl,t.image_url,t.image,o?.[0]);i&&(n.imageUrl=i),o&&o.length>1&&(n.images=o.filter(g=>!!g).map(String));const a=B(t.price_discounted),c=B(t.price),y=a||c;y>0&&(n.price=String(y));const f=a>0?c:0;f>0&&(n.originalPrice=String(f));const d=O(t.brand);d&&(n.brand=d);const s=B(t.rating);s>0&&(n.rating=s);const u=B(t.review_count)||B(t.reviewCount);u>0&&(n.reviewCount=u);const l=O(t.cart_code,t.cartCode);l&&(n.cartCode=l),typeof t.in_stock=="boolean"&&(n.inStock=t.in_stock),typeof t.inStock=="boolean"&&(n.inStock=t.inStock);const m=t.category_names;return Array.isArray(m)&&(n.categoryNames=m.map(String)),n}function Z(e){const t=Oe(e);if(!t)return e;const r=t.category_names,n=Array.isArray(r)?r:void 0,o=t.images,i=Array.isArray(o)?o:void 0,a={sku:t.sku,name:t.name||t.title,url:t.url,price:t.price,currency:t.price_currency||t.currency,category:n?.[n.length-1]??void 0,category_names:n?n.slice(0,4):void 0,image:i?i[0]:t.image,in_stock:t.in_stock,rating:t.rating,review_count:t.review_count};for(const c of Object.keys(a))a[c]===void 0&&delete a[c];return a}function yr(e){return Array.isArray(e)?e.map(Z).filter(t=>!!t):[]}function O(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function B(e){const t=Number(e);return Number.isFinite(t)?t:0}function Re(e){return Array.isArray(e)?e.map(String).filter(Boolean):typeof e=="string"&&e?[e]:[]}function mr(e,t,r={}){return`${e}:${r.version||"v2"}:${v(t)}`}function pr(e,t={}){return Ue(e).map(r=>Me(typeof r=="string"?r:r.sku,t.locale)).filter(Boolean).filter((r,n,o)=>o.indexOf(r)===n).sort((r,n)=>ee(r,n,t.locale)).slice(0,t.limit||16).join(",")}function gr(e,t={}){return v(Ue(e).map(r=>wr(r,t)).filter(r=>!!r).sort((r,n)=>ee(String(r.sku||r.name||""),String(n.sku||n.name||""),t.locale)).slice(0,t.limit||16))}function hr(e,t){return C(e,t)}function v(e){let t=2166136261;const r=br(e);for(let n=0;n<r.length;n+=1)t^=r.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function wr(e,t){if(!e||typeof e!="object"||Array.isArray(e))return null;const r=e,n=t.mapProduct?.(r);if(n)return N(n);const o=Z(r);return o&&typeof o=="object"&&!Array.isArray(o)?N(Sr(o,t)):null}function Ue(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"||!!(t&&typeof t=="object"&&!Array.isArray(t))):[]}function br(e){return JSON.stringify(N(e))}function N(e){return Array.isArray(e)?e.map(N):!e||typeof e!="object"?e:Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[r])=>t.localeCompare(r)).map(([t,r])=>[t,N(r)]))}function Sr(e,t){return{sku:Me(e.sku,t.locale),name:C(e.name,t.locale),url:C(e.url,t.locale),price:e.price,currency:C(e.currency,t.locale),category:C(e.category,t.locale),category_names:kr(e.category_names,t.locale,16),image:C(e.image,t.locale),in_stock:e.in_stock,rating:e.rating,review_count:e.review_count}}function Me(e,t){return C(e,t).toUpperCase()}function C(e,t){return typeof e=="string"?e.trim().replace(/\s+/gu," ").toLocaleLowerCase(t||void 0):""}function ee(e,t,r){return e.localeCompare(t,r,{numeric:!0})}function kr(e,t,r){return Array.isArray(e)?e.map(n=>C(n,t)).filter(Boolean).sort((n,o)=>ee(n,o,t)).slice(0,r):void 0}var Ar="entries",_r=1,Er={volatile:"Hot per-page state and sensitive request context.",session:"Current-visit tool context without raw tokens or PII-heavy payloads.",local:"Small, non-sensitive capability facts or user preferences.",indexedDb:"Larger product/search payload caches with short TTLs."},Be=new Map;function te(){return Date.now()}function re(e){return e?.expiresAt!=null&&e.expiresAt<=te()}function ne(e,t){return{value:e,createdAt:te(),expiresAt:t?te()+t:null}}function xr(e,t,r){try{const n=e.getItem(`${t}${r}`);if(!n)return null;const o=JSON.parse(n);return re(o)?(e.removeItem(`${t}${r}`),null):o.value}catch{return null}}function Tr(e,t,r,n,o){try{return e.setItem(`${t}${r}`,JSON.stringify(ne(n,o))),!0}catch{return!1}}function Pr(e,t,r){try{e.removeItem(`${t}${r}`)}catch{}}function ve(e){try{return window[e]}catch{return null}}function Ne(e,t){return e?{get:r=>xr(e,t,r),set:(r,n,o={})=>Tr(e,t,r,n,o.ttlMs),remove:r=>Pr(e,t,r)}:{get:()=>null,set:()=>!1,remove:()=>{}}}function Ir(e,t){const r=t.dbName||`gengage-${e}`,n=t.dbStore||Ar,o=t.dbVersion||_r,i=new Map;let a=null;const c=()=>"indexedDB"in window?a||(a=new Promise(s=>{const u=indexedDB.open(r,o);u.onupgradeneeded=()=>{u.result.createObjectStore(n,{keyPath:"key"})},u.onsuccess=()=>s(u.result),u.onerror=()=>s(null),u.onblocked=()=>s(null)}),a):Promise.resolve(null);return{volatileEntries:i,idbGet:async s=>{const u=await c();return u?new Promise(l=>{const m=u.transaction(n,"readwrite").objectStore(n),g=m.get(s);g.onsuccess=()=>{const h=g.result;if(!h||re(h)){h&&m.delete(s),l(null);return}l(h.value)},g.onerror=()=>l(null)}):null},idbSet:async(s,u,l={})=>{const m=await c();return m?new Promise(g=>{const h=m.transaction(n,"readwrite");h.oncomplete=()=>g(!0),h.onerror=()=>g(!1),h.objectStore(n).put({key:s,...ne(u,l.ttlMs)})}):!1},idbRemove:async s=>{const u=await c();u&&u.transaction(n,"readwrite").objectStore(n).delete(s)}}}function oe(e,t={}){const r=window,n=r.gengage||(r.gengage={}),o=n.memory||(n.memory={}),i=o[e];if(i)return i;const a=Be.get(e)||Ir(e,t);Be.set(e,a);const c=t.sessionPrefix||`gengage:${e}:session:`,y=t.localPrefix||`gengage:${e}:local:`,d={get:l=>{const m=a.volatileEntries.get(l);return m?re(m)?(a.volatileEntries.delete(l),null):m.value:null},set:(l,m,g={})=>(a.volatileEntries.set(l,ne(m,g.ttlMs)),!0),remove:l=>{a.volatileEntries.delete(l)},clear:()=>a.volatileEntries.clear()},s={get:a.idbGet,set:a.idbSet,remove:a.idbRemove},u={accountId:e,volatile:d,session:Ne(ve("sessionStorage"),c),local:Ne(ve("localStorage"),y),indexedDb:s,stableKey:v,policy:{...Er,...t.policy||{}}};o[e]=u;for(const l of t.aliases||[])o[l]=u;return u}var q="__gengageAgentFetchBridge",Cr=1e3*60*60*24*14;function jr({accountId:e,streamTransport:t,endpoints:r={},endpointCache:n}){if(!e)throw new Error("accountId is required.");if(typeof t!="function")throw new Error("streamTransport is required.");const o=Or(),i=`https://gengage-injector.invalid/${encodeURIComponent(e)}`,a=new Set,c=n?Nr({accountId:e,endpointCache:n,fetchImpl:o.originalFetch}):void 0,y=f=>{const d=`${i}/chat/${f}`;a.add(d);const s=r[f],u={streamTransport:t,endpoint:f};s&&(u.endpointHandler=s),c&&(u.endpointCache=c),o.routes.set(d,u)};y("process_action");for(const f of Object.keys(r))f!=="process_action"&&y(f);return{middlewareUrl:i,stop(){for(const f of a)o.routes.delete(f);Rr(o)}}}function Or(){const e=window,t=e[q];if(t)return t;const r=e.fetch.bind(e),n={routes:new Map,originalFetch:r,installedFetch:r};return n.installedFetch=(o,i)=>{const a=De(o),c=n.routes.get(a);return c?Mr(c,o,i):r(o,i)},e.fetch=n.installedFetch,e[q]=n,n}function Rr(e){if(e.routes.size>0)return;const t=window;t.fetch===e.installedFetch&&(t.fetch=e.originalFetch),t[q]===e&&delete t[q]}function De(e){return typeof e=="string"?e:e instanceof URL?e.href:e?.url||""}function Le(e,t){if(t?.signal)return t.signal;if(typeof Request<"u"&&e instanceof Request)return e.signal}function $e(e,t){return t?.body!==void 0&&t?.body!==null?t.body:typeof Request<"u"&&e instanceof Request?e.clone().text():null}async function Ur(e,t){const r=$e(e,t);if(r instanceof FormData){const o=r.get("request"),i=r.get("attachment");return{request:JSON.parse(String(o||"{}")),...i instanceof File?{attachment:i}:{}}}const n=await Promise.resolve(r);return typeof n=="string"?{request:JSON.parse(n||"{}")}:{request:{}}}async function Mr(e,t,r){if(e.endpoint&&e.endpoint!=="process_action"&&e.endpointHandler){const f=new AbortController,d=Le(t,r);let s=null;if(d){const u=()=>f.abort();d.aborted&&u(),d.addEventListener("abort",u,{once:!0}),s=()=>d.removeEventListener("abort",u)}try{const u=await Br(t,r),l={accountId:vr(t),endpoint:e.endpoint,signal:f.signal},m=Dr(e.endpointCache,e.endpoint,u,l.accountId);if(m){const h=await Lr(e.endpointCache,m,f.signal);if(h)return zr(h)}const g=await e.endpointHandler(u,l);return m&&g.ok&&await $r(e.endpointCache,m,g.clone(),f.signal),g}finally{s?.()}}const n=new TextEncoder,o=new AbortController,i=Le(t,r);let a=!1,c=null;const y=new ReadableStream({async start(f){const d=l=>{a||f.enqueue(n.encode(`${JSON.stringify(l)}
4
+ `))},s=()=>{a||(a=!0,c?.(),f.close())},u=l=>{d({type:"error",code:l?.code||"agent_bridge_error",message:l instanceof Error?l.message:String(l)}),d({type:"done"}),s()};if(i){const l=()=>{o.abort(),a||(a=!0,c?.(),f.error(new DOMException("Aborted","AbortError")))};if(i.aborted){l();return}i.addEventListener("abort",l,{once:!0}),c=()=>i.removeEventListener("abort",l)}try{const{request:l,attachment:m}=await Ur(t,r),g=e.streamTransport(l,{onTextChunk:(h,k,w={})=>d({type:"text_chunk",content:h,final:k===!0,...w}),onUISpec:(h,k,w,ae)=>d({type:"ui_spec",spec:h,widget:k,...w?{panelHint:w}:{},...ae?{clearPanel:!0}:{}}),onAction:h=>{d(h?.type==="action"?h:{type:"action",action:h})},onMetadata:h=>{d(h?.type==="metadata"?h:{type:"metadata",...h})},onError:u,onDone:()=>{d({type:"done"}),s()}},o.signal,m);Vr(g)&&(await g,o.signal.aborted||(d({type:"done"}),s()))}catch(l){o.signal.aborted||u(l)}},cancel(){o.abort(),c?.(),a=!0}});return new Response(y,{status:200,headers:{"Content-Type":"application/x-ndjson"}})}async function Br(e,t){const r=await Promise.resolve($e(e,t));return typeof r!="string"||r.trim()===""?{}:JSON.parse(r)}function vr(e){try{const[t]=new URL(De(e)).pathname.split("/").filter(Boolean);return decodeURIComponent(t||"")}catch{return""}}function Nr({accountId:e,endpointCache:t,fetchImpl:r}){return{accountId:e,beUrl:t.beUrl,...t.parentUrl?{parentUrl:t.parentUrl}:{},ttlMs:t.ttlMs??Cr,policies:t.policies,fetchImpl:r,jwtProvider:J({accountId:e,...t.devJwtSecret?{devJwtSecret:t.devJwtSecret}:{},...t.tokenBrokerUrl?{tokenBrokerUrl:t.tokenBrokerUrl}:{},...t.tokenBrokerAudience?{tokenBrokerAudience:t.tokenBrokerAudience}:{},fetchImpl:r})}}function Dr(e,t,r,n){if(!e)return null;const o=e.policies[t];if(!o)return null;const i=o(r,{accountId:n,endpoint:t});return!i?.partition||!i?.key?null:{partition:i.partition,key:i.key,ttlMs:i.ttlMs??e.ttlMs}}async function Lr(e,t,r){const n=Je(e.accountId,t),o=await Hr(e.accountId,n);if(Ke(o))return o;const i=await Fr(e,t,r);return i?(await ze(e.accountId,n,i,t.ttlMs),i):null}async function $r(e,t,r,n){try{const o=await Jr(r);if(Wr(o.body))return;const i=Je(e.accountId,t);await ze(e.accountId,i,o,t.ttlMs),qr(e,t,o,n)}catch{}}async function Fr(e,t,r){try{const n=await e.fetchImpl(qe(e.beUrl),{method:"POST",headers:await Fe(e,r),body:JSON.stringify({partition:t.partition,key:t.key}),signal:r});if(!n.ok)return null;const o=await n.json();return o.hit===!0&&Ke(o.payload)?o.payload:null}catch{return null}}async function qr(e,t,r,n){try{await e.fetchImpl(qe(e.beUrl),{method:"POST",headers:await Fe(e,n),body:JSON.stringify({partition:t.partition,key:t.key,ttl_s:Math.max(1,Math.ceil(t.ttlMs/1e3)),payload:r}),signal:n})}catch{}}async function Fe(e,t){return{authorization:`Bearer ${await e.jwtProvider({signal:t,parentUrl:e.parentUrl||Kr()})}`,"content-type":"application/json",accept:"application/json"}}function Kr(){try{return window.location?.href||""}catch{return""}}function qe(e){return`${String(e).replace(/\/+$/u,"")}/v1/cache`}async function Jr(e){return{status:e.status,statusText:e.statusText,headers:[...e.headers.entries()].filter(([t])=>Gr(t)),body:await e.text()}}function zr(e){return new Response(e.body,{status:e.status,statusText:e.statusText,headers:new Headers(e.headers)})}function Ke(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;const t=e;return typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.body=="string"&&Array.isArray(t.headers)}function Je(e,t){return`endpoint-response:${v({accountId:e,partition:t.partition,key:t.key})}`}async function Hr(e,t){const r=oe(e);return r.volatile.get(t)||await r.indexedDb.get(t)||r.local.get(t)}async function ze(e,t,r,n){const o=oe(e);o.volatile.set(t,r,{ttlMs:n}),await o.indexedDb.set(t,r,{ttlMs:n})||o.local.set(t,r,{ttlMs:n})}function Gr(e){return["content-type","cache-control"].includes(e.toLowerCase())}function Wr(e){return/"_error"\s*:/u.test(e)||/"type"\s*:\s*"error"/u.test(e)}function Vr(e){return e!==null&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Yr({accountId:e,beUrl:t,devJwtSecret:r,tokenBrokerUrl:n,tokenBrokerAudience:o,workerUrl:i,defaultLocale:a="en-GB",accountModule:c,tools:y={},beacon:f,allowBlobWorker:d=!1}){if(!e)throw new Error("accountId is required.");if(!t)throw new Error("beUrl is required. The injector owns backend URLs; the SDK has no default.");if(!i)throw new Error("workerUrl is required.");const s=window,u=s.GengageAssistantInjector||(s.GengageAssistantInjector={}),l=u[e]||(u[e]={});if(l.agentController)return l.agentController;const m=ie(i)||d?He(i,`gengage-${e}-agent`,{allowBlobWorker:d}):null;m||f?.({type:"agentRuntime",accountId:e,transport:"main-thread",reason:"cross-origin-worker-url",workerUrl:i}),l.streamTransport=m?Pe({accountId:e,worker:m.worker,beUrl:t,...r?{devJwtSecret:r}:{},...n?{tokenBrokerUrl:n}:{},...o?{tokenBrokerAudience:o}:{},defaultLocale:a,tools:y,...f?{beacon:f}:{}}):Ie({accountId:e,accountModule:c,beUrl:t,...r?{devJwtSecret:r}:{},...n?{tokenBrokerUrl:n}:{},...o?{tokenBrokerAudience:o}:{},defaultLocale:a,tools:y,...f?{beacon:f}:{}});const g={type:"agent",stop(){delete l.streamTransport,m?.worker.terminate(),m?.cleanup(),delete l.agentController},diagnostics(){return{accountId:e,beUrl:t,workerUrl:i,mounted:!0,transport:m?"worker":"main-thread",transportReason:m?"module-worker":"cross-origin-worker-url",flows:Object.keys(c?.flows||{})}}};return l.agentController=g,g}function ie(e){const t=new URL(e,window.location.href);return t.origin===window.location.origin||t.protocol==="blob:"}function He(e,t,r={}){const n=new URL(e,window.location.href);if(ie(e))return{worker:new Worker(n.href,{type:"module",name:t}),cleanup(){}};if(!r.allowBlobWorker)throw new Error("Cross-origin agent workers require allowBlobWorker=true or a same-origin workerUrl.");const o=new Blob([`import ${JSON.stringify(n.href)};
5
+ `],{type:"text/javascript"}),i=URL.createObjectURL(o);try{return{worker:new Worker(i,{type:"module",name:t}),cleanup(){URL.revokeObjectURL(i)}}}catch(a){throw URL.revokeObjectURL(i),a}}function Qr(e=[]){const t={},r=[];return(Array.isArray(e)?e.map(F).filter(n=>!!n):[]).forEach((n,o)=>{const i=`product-${o.toString()}`;r.push(i);const a={sku:n.sku,product:n};t[i]={type:"ProductCard",props:{product:n,index:o,action:{title:n.name,type:"launchSingleProduct",payload:a}}}}),t.root={type:"ProductGrid",props:{layout:"grid"},children:r},{widget:"chat",panelHint:"panel",spec:{root:"root",elements:t}}}function Xr(e){return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ProductDetailsPanel",props:{product:F(e)||e||{}}}}}}}function Zr(e={}){const t=(e.multiple_product_details||e.products||[]).map(F).filter(n=>!!n),r=e.table||{};return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ComparisonTable",props:{products:t,recommended:t.find(n=>n.sku===e.recommended_choice_sku)||t[0],attributes:Object.entries(r).map(([n,o])=>({label:n,values:Array.isArray(o)?o.map(String):[String(o??"")]})),highlights:Re(e.key_differences),specialCases:Re(e.special_considerations),recommendedText:e.recommended_choice,productActions:Object.fromEntries(t.map(n=>[n.sku,{title:n.name,type:"launchSingleProduct",payload:{sku:n.sku,product:n}}]))}}}}}}function en(e=[]){return{widget:"chat",panelHint:"inline",spec:{root:"root",elements:{root:{type:"ActionButtons",props:{buttons:(Array.isArray(e)?e:[]).map(t=>{const r=t.label||t.title||t.shortName||"",n=t.action||t.requestDetails||t.request_details;return!r||!n?.type?null:{label:r,action:{title:r,type:n.type,...n.payload!==void 0?{payload:n.payload}:{}}}}).filter(t=>!!t)}}}}}}function tn(e){return Object.freeze([...e])}var Ge=new Set(["and","are","for","from","the","with"]),rn={token:.26,keyword:.22,category:.18,facet:.16,color:.08,attribute:.06,price:.08,retrieval:.08},nn=["amber","beige","black","blue","blush","bronze","brown","cream","gold","green","grey","ivory","lilac","mixed","orange","pastel","pink","purple","red","silver","white","yellow"];function T(e){return String(e??"").normalize("NFKD").replace(new RegExp("\\p{Diacritic}","gu"),"").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function A(e,t=Ge){const r=t instanceof Set?t:new Set([...Ge,...t]),n=new Set,o=[];for(const i of T(e).split(/\s+/u))i.length<3||r.has(i)||n.has(i)||(n.add(i),o.push(i));return o}function D(e,t={}){if(sn(e))return e;const r=t.facetKeys,n=S(e.category_names??e.category),o=S(e.category_ids),i=un(e.facet_hits),a=Object.entries(i).filter(([g])=>!r||r.some(h=>T(h)===T(g))).map(([,g])=>g),c=x(e.name,e.title),y=x(e.brand),f=t.sourceKeywords??[],d=[c,y,...n,...a,...S(e.promotions),x(e.description),...f].join(" "),s=A(d,t.stopWords),u=x(t.sourceProductType,fn(n,c,s),s[0]),l=P([...dn(d,nn),...Object.entries(i).filter(([g])=>/colou?r/iu.test(g)).flatMap(([,g])=>A(g,t.stopWords))]),m=P([...a.flatMap(g=>A(g,t.stopWords)),...S(e.promotions).flatMap(g=>A(g,t.stopWords))]).slice(0,24);return{sku:x(e.sku),title:c,brand:y,productType:u,categoryNames:n,categoryIds:o,facets:i,keywords:P([...f.flatMap(g=>A(g,t.stopWords)),...s]).slice(0,12),tokens:s,colors:l,attributes:m,price:ln(e)}}function on(e,t={}){const r=x(e.product_type,e.productType),n=x(e.title,r,S(e.keywords).join(" ")),o=P([...S(e.keywords),...S(e.colors),...S(e.materials),...S(e.styles),...S(e.attributes)]);return D({sku:"__photo__",name:n,category_names:r?[r]:[],facet_hits:{colors:S(e.colors).join(", "),materials:S(e.materials).join(", "),styles:S(e.styles).join(", "),attributes:S(e.attributes).join(", ")},promotions:o},{...t,sourceProductType:r,sourceKeywords:o})}function an(e,t={}){const r=D(e,t);return P([...t.sourceQueries??[],K([r.productType,...r.colors.slice(0,1),...r.attributes.slice(0,2)]),K([r.productType,...r.keywords.slice(0,3)]),K([r.categoryNames[r.categoryNames.length-1],...r.keywords.slice(0,2)]),K(r.title.split(/\s+/u).slice(0,6)),r.productType].map(n=>n.trim()).filter(Boolean)).slice(0,t.queryLimit??6)}function We(e,t,r={}){const n={...rn,...r.weights},o=D(t,r),i=[],a=R(e.tokens,o.tokens),c=R(e.keywords,o.tokens),y=yn(e.categoryNames,o.categoryNames)||R(Ve(e.categoryNames),Ve(o.categoryNames)),f=R(e.attributes,o.attributes),d=R(e.colors,o.colors),s=R(e.attributes,o.tokens),u=mn(e.price,o.price),l=pn(o.sku,r.hitCounts)>0?1:0,m=gn(e,o),g=a*n.token+c*n.keyword+y*n.category+f*n.facet+d*n.color+s*n.attribute+u*n.price+l*n.retrieval,h=hn(m?g:g*.35);return m&&e.productType&&e.productType===o.productType&&i.push("same product type"),y>.4&&i.push("similar category"),f>.2&&i.push("matching product attributes"),d>0&&i.push("matching colour"),u>.8&&i.push("similar price"),m||i.push("weaker product-type match"),{score:Number(h.toFixed(4)),reasons:i}}function cn(e,t,r={}){const n=D(e,r),o=new Set([n.sku,...r.ignoreSkus??[]].filter(Boolean));return t.filter(i=>{const a=x(i.sku);return a&&!o.has(a)}).map(i=>{const a=We(n,i,r);return{...i,similarity_score:a.score,similarity_reasons:a.reasons}}).sort((i,a)=>a.similarity_score-i.similarity_score).slice(0,Math.max(1,Math.min(r.limit??12,100)))}function sn(e){return!!(e&&typeof e=="object"&&Array.isArray(e.tokens))}function x(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function S(e){return Array.isArray(e)?e.map(t=>x(t)).filter(Boolean):typeof e=="string"&&e.trim()?e.split(/[,;/|]+/u).map(t=>t.trim()).filter(Boolean):[]}function un(e){return!e||typeof e!="object"||Array.isArray(e)?{}:Object.fromEntries(Object.entries(e).map(([t,r])=>[t,x(r)]).filter(([,t])=>t))}function ln(e){const t=Number(e.price_discounted);if(Number.isFinite(t)&&t>0)return t;const r=Number(e.price);return Number.isFinite(r)&&r>0?r:0}function P(e){const t=new Set,r=[];for(const n of e){const o=T(n);!o||t.has(o)||(t.add(o),r.push(o))}return r}function dn(e,t){const r=` ${T(e)} `;return t.filter(n=>r.includes(` ${T(n)} `))}function fn(e,t,r){const n=T(e[e.length-1]??e[0]??"");if(n){const o=A(n),i=new Set(A(t));return o.find(a=>i.has(a))??o[0]??n}return r[0]??""}function K(e){return e.map(t=>T(t)).filter(Boolean).join(" ").replace(/\s+/gu," ").trim().slice(0,120)}function Ve(e){return e.flatMap(t=>A(t))}function R(e,t){const r=P(e),n=new Set(P(t));return r.length===0||n.size===0?0:r.filter(o=>n.has(o)).length/r.length}function yn(e,t){const r=P(e),n=new Set(P(t));return r.length===0||n.size===0?0:r.filter(o=>n.has(o)).length/r.length}function mn(e,t){return e<=0||t<=0?0:Math.min(e,t)/Math.max(e,t)}function pn(e,t){return!e||!t?0:typeof t.get=="function"?t.get(e)??0:t[e]??0}function gn(e,t){if(!e.productType||!t.productType||e.productType===t.productType)return!0;const r=new Set(A(e.productType)),n=new Set([...A(t.productType),...t.tokens]);return[...r].some(o=>n.has(o))}function hn(e){return Math.max(0,Math.min(1,e))}function wn(e){const t=(e?.chat||e?._chat)?.root||e?._chat?.root;return t?t.getRootNode?.()?.host||t:Array.from(document.querySelectorAll("*")).find(r=>r.shadowRoot?.querySelector?.(".gengage-chat-root, .gengage-chat-launcher-container"))}function bn(e,t){const r=wn(e);r?.style&&(t?r.style.removeProperty("display"):r.style.setProperty("display","none","important")),t||(e?.chat||e?._chat)?.close?.()}var Sn="nd_be_url";function kn(e,t){const r=An()||e.beUrl||t;if(!r)throw new Error("resolveBeUrl: backend URL is required. The injector must supply a fallback URL; the SDK has no default.");return r}function An(){try{const e=new URLSearchParams(window.location.search).get(Sn)?.trim();if(!e)return null;const t=new URL(e);return t.protocol!=="https:"&&t.protocol!=="http:"?null:t.toString().replace(/\/+$/u,"")}catch{return null}}var _n=["addToCart","search","searchKeyword","facetedSearch","searchGiftOptions","similaritySearch"];function En(e,t,r={}){const n=window,o=n.gengage||(n.gengage={}),i=o.tools||(o.tools={});i[e]=t;for(const a of r.accountAliases||[])i[a]=t;if(r.exposeStandardAliases!==!1)for(const a of r.standardAliases||_n){const c=t[a];typeof c=="function"&&(i[a]=i[a]||c)}return t}function xn({getPageType:e,getProduct:t}){return()=>({url:window.location.href,title:document.title,pageType:e(),product:t()})}function Tn({accountId:e,getPageType:t,getProduct:r,getToolNames:n,getSearchCapabilities:o,getMemory:i}){return async()=>({accountId:e,url:window.location.href,pageType:t(),productSku:r()?.sku??null,toolNames:n(),...o?{searchCapabilities:o()}:{},...i?{memoryPolicy:i().policy}:{},timestamp:new Date().toISOString()})}function Pn({accountId:e,runtimeFile:t="runtime.js",startExport:r="start",globalBaseUrlKey:n,errorLabel:o}={}){if(!e)throw new Error("accountId is required.");const i=o||e,a=window,c=()=>{const s=a.GengageInjectorConfig||{},u=s[e]||{};return{...s,...u}},y=()=>{const s=c();if(s.runtimeUrl)return s.runtimeUrl;const u=s.assetBaseUrl||s.baseUrl||document.currentScript?.getAttribute("src")||(n?a[n]:null);if(!u)throw new Error(`${i} runtime URL cannot be resolved.`);return new URL(t,u).href},f=a.GengageAssistantInjector||(a.GengageAssistantInjector={}),d=f[e]||(f[e]={});return d.loaderPromise||(d.loaderPromise=import(y()).then(s=>{const u=s[r];if(typeof u!="function")throw new Error(`${i} runtime export ${r} is unavailable.`);return u()}).catch(s=>{throw delete d.loaderPromise,console.error(`[Gengage][${e}] runtime load failed`,s),s})),d.loaderPromise}function In(e){const t=e?.payload;if(typeof t=="string")return t;if(t&&typeof t=="object"&&"text"in t){const n=t.text;if(typeof n=="string")return n}const r=e?.action;return r&&typeof r.payload=="string"?r.payload:r&&typeof r.title=="string"?r.title:""}p.AgentError=L,p.ContextStore=de,p.action=qt,p.actionButtonsUiSpec=en,p.beErrorToAgentError=z,p.buildPhotoSimilarityProfile=on,p.buildProductSimilarityProfile=D,p.buildSimilarityQueries=an,p.canUseModuleWorker=ie,p.caughtToStreamError=he,p.comparisonUiSpec=Zr,p.createBrowserMemory=oe,p.createDiagnosticsTool=Tn,p.createFlow=tn,p.createInjectorAdapter=Pe,p.createMainThreadInjectorAdapter=Ie,p.createModuleWorker=He,p.createReadPageTool=xn,p.done=W,p.elapsedMs=j,p.error=_e,p.httpErrorToAgentError=ge,p.installBrowserTools=En,p.installFetchTransportBridge=jr,p.llmCacheKey=mr,p.metadata=$t,p.mountAccount=Yr,p.normalizeProduct=F,p.normalizeSimilarityText=T,p.nowIso=se,p.productDetailsUiSpec=Xr,p.productFactsKey=gr,p.productSkuKey=pr,p.productsUiSpec=Qr,p.rankSimilarProducts=cn,p.requestText=In,p.resolveBeUrl=kn,p.resolveFlow=Ee,p.scoreSimilarityCandidate=We,p.setAssistantHostVisible=bn,p.stableKey=v,p.startLazyRuntimeLoader=Pn,p.textChunk=Ae,p.textKey=hr,p.tokenizeSimilarityText=A,p.trimProductFactsCore=Z,p.trimProductFactsListCore=yr,p.uiSpec=Ft})(this.Gengage=this.Gengage||{});
@@ -1,4 +1,4 @@
1
- import { i as U } from "./widget-base-TZjXRr3u.js";
1
+ import { i as U } from "./widget-base-DoZrhVze.js";
2
2
  var z = ({ element: e, renderElement: t }) => {
3
3
  if (!e.children || e.children.length === 0) return null;
4
4
  const r = document.createElement("div");
@@ -0,0 +1,152 @@
1
+ /**
2
+ * InlineLauncher — host-DOM launcher button that mounts beside a page element
3
+ * (e.g. header search). Follows the same config-driven pattern as
4
+ * `createFloatingLauncher`: the chat widget runtime calls
5
+ * `createInlineLauncher()` when `config.inlineLauncher` is set.
6
+ *
7
+ * In the injector, pass selectors and styling through chat config:
8
+ *
9
+ * chat: {
10
+ * inlineLauncher: {
11
+ * hostSelector: '#searchBoxComponentID',
12
+ * siblingSelector: '.mini-search',
13
+ * siblingPlacement: 'before',
14
+ * title: 'Ask our expert',
15
+ * iconUrl: 'https://…/avatar.png',
16
+ * primaryColor: '#ec6e00',
17
+ * },
18
+ * }
19
+ */
20
+ export interface InlineLauncherMobileHostOptions {
21
+ /** Host element for the inline row on compact viewports. */
22
+ hostSelector: string;
23
+ /** Sibling co-located in the row (e.g. mobile search trigger). */
24
+ siblingSelector?: string;
25
+ siblingPlacement?: 'before' | 'after';
26
+ siblingRestoreParentSelector?: string;
27
+ rowPlacement?: 'start' | 'end';
28
+ }
29
+ export interface InlineLauncherSizeOptions {
30
+ /** Gap between sibling search and launcher button in the row. */
31
+ rowGap?: string;
32
+ /** Button min-height. */
33
+ buttonHeight?: string;
34
+ /** Button padding. */
35
+ buttonPadding?: string;
36
+ /** Gap between icon, title and spark inside the button. */
37
+ buttonGap?: string;
38
+ /** Title font size. */
39
+ fontSize?: string;
40
+ /** Avatar wrapper size. */
41
+ iconSize?: string;
42
+ /** Avatar image size. */
43
+ iconImageSize?: string;
44
+ /** Spark wrapper size. */
45
+ sparkSize?: string;
46
+ /** Spark SVG size. */
47
+ sparkIconSize?: string;
48
+ }
49
+ export interface InlineLauncherOptions {
50
+ /** Host element that receives the inline launcher row. */
51
+ hostSelector: string;
52
+ /** CSS class for the flex row wrapper. Default: 'gengage-inline-launcher-row' */
53
+ rowClassName?: string;
54
+ /** Optional sibling element co-located in the row (e.g. site search input). */
55
+ siblingSelector?: string;
56
+ /**
57
+ * Sibling position relative to the launcher button.
58
+ * `'before'` → sibling first, button after (search + launcher).
59
+ * Default: `'before'`.
60
+ */
61
+ siblingPlacement?: 'before' | 'after';
62
+ /**
63
+ * Where the flex row is inserted inside the host when first created.
64
+ * `'start'` keeps dropdown/sibling overlays below the search row (idefix-style headers).
65
+ * Default: `'end'`.
66
+ */
67
+ rowPlacement?: 'start' | 'end';
68
+ /**
69
+ * Parent element that receives the sibling when the inline row is torn down.
70
+ * Defaults to `hostSelector`.
71
+ */
72
+ siblingRestoreParentSelector?: string;
73
+ /** Visible label text. */
74
+ title?: string;
75
+ /** Avatar / icon image URL. */
76
+ iconUrl?: string;
77
+ /** Brand accent color. Default: '#6366f1' */
78
+ primaryColor?: string;
79
+ /** Body text color. Default: '#222222' */
80
+ textColor?: string;
81
+ /** CSS font-family string. Default: 'inherit' */
82
+ fontFamily?: string;
83
+ /** Button corner radius. Default: '3px' */
84
+ borderRadius?: string;
85
+ /** Accessible name for the button. Falls back to `title`. */
86
+ ariaLabel?: string;
87
+ /** Show the decorative spark icon. Default: true */
88
+ showSparkIcon?: boolean;
89
+ /**
90
+ * Minimum viewport width (inclusive) required to mount inline on desktop.
91
+ * Below this width the row is removed and the floating launcher is shown,
92
+ * unless `enableOnMobile` is true.
93
+ * Default: 0 (always eligible when page type allows).
94
+ */
95
+ desktopMinWidth?: number;
96
+ /**
97
+ * When true, inline launcher also mounts below `desktopMinWidth` (mobile/tablet).
98
+ * Default: false.
99
+ */
100
+ enableOnMobile?: boolean;
101
+ /**
102
+ * Page types where inline launcher must not mount (floating launcher shown instead).
103
+ * Default: `['pdp']`.
104
+ */
105
+ disabledPageTypes?: string[];
106
+ /**
107
+ * Hide the shadow-DOM floating launcher while inline is mounted.
108
+ * Default: true.
109
+ */
110
+ hideFloatingLauncher?: boolean;
111
+ /** Max animation frames to wait for host/sibling DOM. Default: 90. */
112
+ mountPollFrames?: number;
113
+ /** Debounce for resize/orientation sync in ms. Default: 90. */
114
+ debounceMs?: number;
115
+ /** Stable id for the launcher button. Default: 'gengage-inline-launcher'. */
116
+ buttonId?: string;
117
+ /**
118
+ * Optional DOM targets for compact viewports when `enableOnMobile` is true
119
+ * and width is below `desktopMinWidth`. Falls back to desktop selectors when omitted.
120
+ */
121
+ mobileHost?: InlineLauncherMobileHostOptions;
122
+ /**
123
+ * Optional size overrides. Desktop values apply by default; `size.mobile`
124
+ * applies below the compact breakpoint (`desktopMinWidth` when `enableOnMobile`, else 576px).
125
+ */
126
+ size?: InlineLauncherSizeOptions & {
127
+ mobile?: InlineLauncherSizeOptions & {
128
+ hideTitle?: boolean;
129
+ hideSpark?: boolean;
130
+ hideLogo?: boolean;
131
+ };
132
+ };
133
+ }
134
+ export interface InlineLauncherKit {
135
+ /** Whether the inline row is currently mounted in the host DOM. */
136
+ readonly isMounted: boolean;
137
+ /** Attempt mount/unmount based on viewport + page type. Returns true when mounted. */
138
+ sync(pageType?: string | undefined): Promise<boolean>;
139
+ /** Toggle active styling while the chat drawer is open. */
140
+ setActive(active: boolean): void;
141
+ /** Release listeners, restore sibling placement, remove injected DOM. */
142
+ destroy(): void;
143
+ }
144
+ interface InlineLauncherDeps {
145
+ shadowRoot: ShadowRoot | null;
146
+ getPageType: () => string | undefined;
147
+ }
148
+ interface InlineLauncherCallbacks {
149
+ onClick: () => void;
150
+ }
151
+ export declare function createInlineLauncher(options: InlineLauncherOptions, callbacks: InlineLauncherCallbacks, deps: InlineLauncherDeps): InlineLauncherKit;
152
+ export {};
@@ -3,4 +3,6 @@ export { chatCatalog } from './catalog.js';
3
3
  export type { ChatCatalog, ChatComponentName } from './catalog.js';
4
4
  export { createFloatingLauncher } from './components/FloatingLauncher.js';
5
5
  export type { FloatingLauncherOptions } from './components/FloatingLauncher.js';
6
+ export { createInlineLauncher } from './components/InlineLauncher.js';
7
+ export type { InlineLauncherOptions, InlineLauncherSizeOptions, InlineLauncherMobileHostOptions, } from './components/InlineLauncher.js';
6
8
  export type { ActionEnrichmentContext, BackendRequestMeta, InjectorAdapter, ProcessActionRequest, StreamCallbacks, } from '../common/transport.js';
@@ -33,6 +33,7 @@ export declare class GengageChat extends BaseWidget<ChatWidgetConfig> {
33
33
  private _backdropEl;
34
34
  private _launcher;
35
35
  private _floatingLauncher;
36
+ private _inlineLauncher;
36
37
  private _drawer;
37
38
  private _bridge;
38
39
  private _drawerVisible;
@@ -156,7 +157,9 @@ export declare class GengageChat extends BaseWidget<ChatWidgetConfig> {
156
157
  protected onHide(): void;
157
158
  private _setupLauncherAnchor;
158
159
  syncLauncherAnchor(): void;
160
+ syncInlineLauncher(): void;
159
161
  private _syncLauncherAnchor;
162
+ private _setupInlineLauncher;
160
163
  protected onDestroy(): void;
161
164
  open(options?: {
162
165
  state?: 'full' | 'half';
@@ -2,6 +2,7 @@ import type { AddToCartHandlerResult, AddToCartParams, BaseWidgetConfig, ActionP
2
2
  import type { UnknownActionPolicy } from '../common/config-schema.js';
3
3
  import type { PillLauncherOptions } from '../common/pill-launcher.js';
4
4
  import type { FloatingLauncherOptions } from './components/FloatingLauncher.js';
5
+ import type { InlineLauncherOptions } from './components/InlineLauncher.js';
5
6
  import type { UISpecDomRegistry, UISpecRendererOverrides } from '../common/renderer/index.js';
6
7
  export interface ChatWidgetConfig extends BaseWidgetConfig {
7
8
  /**
@@ -43,6 +44,11 @@ export interface ChatWidgetConfig extends BaseWidgetConfig {
43
44
  * Floating variant only; mutually exclusive with `pillLauncher` and `launcherImageUrl`.
44
45
  */
45
46
  floatingLauncher?: FloatingLauncherOptions;
47
+ /**
48
+ * Header-embedded launcher that mounts in the host DOM beside a page element.
49
+ * While active, the shadow-DOM floating launcher is hidden. Floating variant only.
50
+ */
51
+ inlineLauncher?: InlineLauncherOptions;
46
52
  /** Tooltip text shown on launcher hover. */
47
53
  launcherTooltip?: string;
48
54
  /** Header display title (overrides i18n.headerTitle). */
@@ -1,13 +1,13 @@
1
- import { c as e, d as t, i as r, l as s, n, o as i, r as l, s as C, t as c, u as d } from "./runtime-CAJp9Ehc.js";
1
+ import { c as e, d as t, f as r, i as s, l as n, n as i, r as l, s as C, t as c, u as d } from "./runtime-BKU-NQXf.js";
2
2
  export {
3
- s as CHAT_SCROLL_ELEMENT_ID,
4
- r as ChatPresentationState,
3
+ d as CHAT_SCROLL_ELEMENT_ID,
4
+ s as ChatPresentationState,
5
5
  c as GengageChat,
6
- n as createChatWidget,
7
- i as createDefaultChatUISpecRegistry,
8
- C as defaultChatUnknownUISpecRenderer,
9
- d as getChatScrollElement,
10
- t as invalidateChatScrollCache,
6
+ i as createChatWidget,
7
+ C as createDefaultChatUISpecRegistry,
8
+ e as defaultChatUnknownUISpecRenderer,
9
+ t as getChatScrollElement,
10
+ r as invalidateChatScrollCache,
11
11
  l as isSimilarsAppendGrid,
12
- e as renderUISpec
12
+ n as renderUISpec
13
13
  };