@gengage/assistant-fe 0.6.1 → 0.6.3

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 (36) hide show
  1. package/dist/agentic/adaptor/fetch-bridge.d.ts +3 -2
  2. package/dist/agentic/index.d.ts +1 -0
  3. package/dist/agentic/index.js +347 -257
  4. package/dist/agentic/similarity.d.ts +77 -0
  5. package/dist/agentic/types.d.ts +2 -0
  6. package/dist/agentic/worker/be-client.d.ts +2 -1
  7. package/dist/agentic/worker.d.ts +1 -0
  8. package/dist/agentic/worker.js +65 -57
  9. package/dist/agentic.iife.js +5 -5
  10. package/dist/{api-paths-C4WzXzyY.js → api-paths-Bidgft9p.js} +1 -1
  11. package/dist/chat-runtime.js +1 -1
  12. package/dist/chat.iife.js +1 -1
  13. package/dist/chat.js +1 -1
  14. package/dist/common/transport.d.ts +7 -0
  15. package/dist/{common-DstAcheX.js → common-DWDSD8LC.js} +1 -1
  16. package/dist/common.js +5 -5
  17. package/dist/{connection-warning-Ddr91Y9x.js → connection-warning-BSO1YDm6.js} +1 -1
  18. package/dist/{fastIntent-XtUvISni.js → fastIntent-9jfo-OnO.js} +1 -1
  19. package/dist/index.js +10 -10
  20. package/dist/native.iife.js +1 -1
  21. package/dist/qna-runtime.js +1 -1
  22. package/dist/qna.iife.js +1 -1
  23. package/dist/qna.js +1 -1
  24. package/dist/{runtime-CcA_r8pw.js → runtime-B-25I0p6.js} +3 -3
  25. package/dist/{runtime-C66Wp6OR.js → runtime-B-lBAc6Z.js} +3 -3
  26. package/dist/{runtime-DJMUL882.js → runtime-BivTyMiH.js} +3 -3
  27. package/dist/{simbut-B6L3fwI7.js → simbut-DytP3AWT.js} +1 -1
  28. package/dist/simbut.iife.js +1 -1
  29. package/dist/simbut.js +1 -1
  30. package/dist/{beauty-consulting-turn-BmPXbkQg.js → similarity-DcfZ0CKT.js} +515 -295
  31. package/dist/{simrel-BB4Jrr32.js → simrel-CJp2qMtU.js} +1 -1
  32. package/dist/simrel-runtime.js +1 -1
  33. package/dist/simrel.iife.js +1 -1
  34. package/dist/simrel.js +2 -2
  35. package/dist/{widget-base-B3Oq8pjs.js → widget-base-UJbh-z_5.js} +1 -1
  36. package/package.json +1 -1
@@ -0,0 +1,77 @@
1
+ export interface SimilarityProductLike {
2
+ sku?: unknown;
3
+ name?: unknown;
4
+ title?: unknown;
5
+ brand?: unknown;
6
+ price?: unknown;
7
+ price_discounted?: unknown;
8
+ category?: unknown;
9
+ category_names?: unknown;
10
+ category_ids?: unknown;
11
+ facet_hits?: unknown;
12
+ promotions?: unknown;
13
+ description?: unknown;
14
+ }
15
+ export interface ProductSimilarityProfile {
16
+ sku: string;
17
+ title: string;
18
+ brand: string;
19
+ productType: string;
20
+ categoryNames: string[];
21
+ categoryIds: string[];
22
+ facets: Record<string, string>;
23
+ keywords: string[];
24
+ tokens: string[];
25
+ colors: string[];
26
+ attributes: string[];
27
+ price: number;
28
+ }
29
+ export interface PhotoSimilaritySignals {
30
+ title?: string;
31
+ product_type?: string;
32
+ productType?: string;
33
+ keywords?: string[];
34
+ colors?: string[];
35
+ materials?: string[];
36
+ styles?: string[];
37
+ attributes?: string[];
38
+ search_queries?: string[];
39
+ searchQueries?: string[];
40
+ }
41
+ export interface SimilarityRankingOptions {
42
+ limit?: number;
43
+ queryLimit?: number;
44
+ ignoreSkus?: string[];
45
+ stopWords?: Iterable<string>;
46
+ facetKeys?: string[];
47
+ sourceProductType?: string;
48
+ sourceKeywords?: string[];
49
+ sourceQueries?: string[];
50
+ hitCounts?: ReadonlyMap<string, number> | Record<string, number>;
51
+ weights?: Partial<SimilarityWeights>;
52
+ }
53
+ export interface SimilarityWeights {
54
+ token: number;
55
+ keyword: number;
56
+ category: number;
57
+ facet: number;
58
+ color: number;
59
+ attribute: number;
60
+ price: number;
61
+ retrieval: number;
62
+ }
63
+ export interface SimilarityScore {
64
+ score: number;
65
+ reasons: string[];
66
+ }
67
+ export type SimilarityRankedProduct<T> = T & {
68
+ similarity_score: number;
69
+ similarity_reasons: string[];
70
+ };
71
+ export declare function normalizeSimilarityText(value: unknown): string;
72
+ export declare function tokenizeSimilarityText(value: unknown, stopWords?: Iterable<string>): string[];
73
+ export declare function buildProductSimilarityProfile(product: SimilarityProductLike | ProductSimilarityProfile, options?: SimilarityRankingOptions): ProductSimilarityProfile;
74
+ export declare function buildPhotoSimilarityProfile(signals: PhotoSimilaritySignals, options?: SimilarityRankingOptions): ProductSimilarityProfile;
75
+ export declare function buildSimilarityQueries(source: SimilarityProductLike | ProductSimilarityProfile, options?: SimilarityRankingOptions): string[];
76
+ export declare function scoreSimilarityCandidate(source: ProductSimilarityProfile, candidate: SimilarityProductLike, options?: SimilarityRankingOptions): SimilarityScore;
77
+ export declare function rankSimilarProducts<T extends SimilarityProductLike>(source: SimilarityProductLike | ProductSimilarityProfile, candidates: T[], options?: SimilarityRankingOptions): Array<SimilarityRankedProduct<T>>;
@@ -31,6 +31,7 @@ export interface BeClient {
31
31
  op: string;
32
32
  input?: unknown;
33
33
  signal?: AbortSignal;
34
+ cacheTtlS?: number;
34
35
  }): Promise<unknown>;
35
36
  }
36
37
  export interface FlowStepCtx {
@@ -45,6 +46,7 @@ export interface BeOpStep {
45
46
  kind: 'be_op';
46
47
  op: string;
47
48
  input: FlowValue<unknown>;
49
+ cacheTtlS?: FlowValue<number | undefined>;
48
50
  out?: string;
49
51
  patch?: FlowPatch;
50
52
  }
@@ -9,7 +9,8 @@ interface InvokeBeOpArgs {
9
9
  parentUrl?: string | undefined;
10
10
  op: string;
11
11
  input?: unknown;
12
+ cacheTtlS?: number | undefined;
12
13
  signal?: AbortSignal | undefined;
13
14
  }
14
- export declare function invokeBeOp({ beUrl, accountId, devJwtSecret, tokenBrokerUrl, tokenBrokerAudience, jwtProvider, parentUrl, op, input, signal, }: InvokeBeOpArgs): Promise<Record<string, unknown>>;
15
+ export declare function invokeBeOp({ beUrl, accountId, devJwtSecret, tokenBrokerUrl, tokenBrokerAudience, jwtProvider, parentUrl, op, input, cacheTtlS, signal, }: InvokeBeOpArgs): Promise<Record<string, unknown>>;
15
16
  export {};
@@ -6,6 +6,7 @@ export { actionButtonsUiSpec, comparisonUiSpec, productDetailsUiSpec, productsUi
6
6
  export { beautyConsultingTurnFlow } from './flow/beauty-consulting-turn.js';
7
7
  export { createFlow } from './flow/create-flow.js';
8
8
  export { resolveFlow } from './flow/dispatch.js';
9
+ export { buildPhotoSimilarityProfile, buildProductSimilarityProfile, buildSimilarityQueries, normalizeSimilarityText, rankSimilarProducts, scoreSimilarityCandidate, tokenizeSimilarityText, type PhotoSimilaritySignals, type ProductSimilarityProfile, type SimilarityProductLike, type SimilarityRankedProduct, type SimilarityRankingOptions, type SimilarityScore, type SimilarityWeights, } from './similarity.js';
9
10
  export { requestText } from './util/request-text.js';
10
11
  export { elapsedMs, nowIso } from './util/time.js';
11
12
  export { invokeBeOp } from './worker/be-client.js';
@@ -1,25 +1,25 @@
1
- import { A as S, C as y, D as B, E as T, M as x, O as J, S as M, T as I, _ as g, a as j, b as A, c as F, d as C, f as P, g as L, h, i as q, j as D, k as R, l as K, m as O, n as W, o as z, p as G, r as _, s as H, t as N, u as Q, v as V, w as X, x as Y, y as Z } from "../beauty-consulting-turn-BmPXbkQg.js";
2
- function $(c) {
3
- const n = self, a = /* @__PURE__ */ new Map(), i = S(n), v = C(i);
1
+ import { A as U, C as E, D as P, E as m, F as J, I as M, L as B, M as I, N as F, O as g, P as C, R as j, S as T, T as L, _ as z, a as R, b as q, c as D, d as K, f as O, g as W, h as G, i as N, j as Q, k as _, l as H, m as V, n as X, o as Y, p as Z, r as $, s as tt, t as et, u as rt, v as h, w as ot, x as at, y as x, z as nt } from "../similarity-DcfZ0CKT.js";
2
+ function it(i) {
3
+ const a = self, n = /* @__PURE__ */ new Map(), c = B(a), S = h(c);
4
4
  let e = null, u = null, l = null, p = "";
5
- n.addEventListener("message", (t) => {
5
+ a.addEventListener("message", (t) => {
6
6
  const r = t.data;
7
7
  if (r) {
8
8
  if (r.type === "abort") {
9
- typeof r.id == "number" && (a.get(r.id)?.abort(), a.delete(r.id));
9
+ typeof r.id == "number" && (n.get(r.id)?.abort(), n.delete(r.id));
10
10
  return;
11
11
  }
12
- r.type === "invoke" && w(r);
12
+ r.type === "invoke" && v(r);
13
13
  }
14
14
  });
15
- async function w(t) {
15
+ async function v(t) {
16
16
  e = {
17
- accountId: String(t.accountId || c.accountId || ""),
17
+ accountId: String(t.accountId || i.accountId || ""),
18
18
  beUrl: t.beUrl || "",
19
19
  ...t.devJwtSecret ? { devJwtSecret: t.devJwtSecret } : {},
20
20
  ...t.tokenBrokerUrl ? { tokenBrokerUrl: t.tokenBrokerUrl } : {},
21
21
  ...t.tokenBrokerAudience ? { tokenBrokerAudience: t.tokenBrokerAudience } : {},
22
- locale: t.defaultLocale || c.defaultLocale || "en-GB",
22
+ locale: t.defaultLocale || i.defaultLocale || "en-GB",
23
23
  parentUrl: t.parentUrl || ""
24
24
  };
25
25
  const r = [
@@ -29,91 +29,99 @@ function $(c) {
29
29
  e.tokenBrokerAudience || ""
30
30
  ].join(`
31
31
  `);
32
- (!l || p !== r) && (l = I(e), p = r), u ||= new B({
32
+ (!l || p !== r) && (l = I(e), p = r), u ||= new C({
33
33
  accountId: e.accountId,
34
34
  locale: e.locale,
35
35
  parentUrl: e.parentUrl,
36
- rpc: i
36
+ rpc: c
37
37
  });
38
38
  const d = new AbortController();
39
- a.set(t.id, d);
39
+ n.set(t.id, d);
40
40
  const s = (o) => {
41
- n.postMessage({
41
+ a.postMessage({
42
42
  id: t.id,
43
43
  type: "event",
44
44
  event: o
45
45
  });
46
46
  };
47
47
  try {
48
- const o = e, U = l;
49
- await P({
48
+ const o = e, f = l;
49
+ await x({
50
50
  request: t.request || {},
51
51
  accountModule: {
52
- ...c,
52
+ ...i,
53
53
  accountId: o.accountId
54
54
  },
55
55
  contextStore: u,
56
- beClient: { invoke({ op: f, input: b, signal: k }) {
57
- return A({
56
+ beClient: { invoke({ op: w, input: y, signal: k, cacheTtlS: b }) {
57
+ return P({
58
58
  beUrl: o.beUrl,
59
59
  accountId: o.accountId,
60
- jwtProvider: U,
60
+ jwtProvider: f,
61
61
  parentUrl: o.parentUrl,
62
- op: f,
63
- input: b,
62
+ op: w,
63
+ input: y,
64
+ cacheTtlS: b,
64
65
  ...k ? { signal: k } : {}
65
66
  });
66
67
  } },
67
- toolBridge: v,
68
+ toolBridge: S,
68
69
  emit: s,
69
- rpc: i,
70
+ rpc: c,
70
71
  signal: d.signal
71
- }), n.postMessage({
72
+ }), a.postMessage({
72
73
  id: t.id,
73
74
  type: "end"
74
75
  });
75
76
  } catch (o) {
76
- d.signal.aborted || (s(y(o)), s(h()), n.postMessage({
77
+ d.signal.aborted || (s(U(o)), s(T()), a.postMessage({
77
78
  id: t.id,
78
79
  type: "end"
79
80
  }));
80
81
  } finally {
81
- a.delete(t.id);
82
+ n.delete(t.id);
82
83
  }
83
84
  }
84
85
  }
85
86
  export {
86
- Y as AgentError,
87
- B as ContextStore,
88
- O as action,
89
- q as actionButtonsUiSpec,
90
- M as beErrorToAgentError,
91
- N as beautyConsultingTurnFlow,
92
- y as caughtToStreamError,
93
- j as comparisonUiSpec,
94
- W as createFlow,
87
+ g as AgentError,
88
+ C as ContextStore,
89
+ at as action,
90
+ K as actionButtonsUiSpec,
91
+ _ as beErrorToAgentError,
92
+ D as beautyConsultingTurnFlow,
93
+ et as buildPhotoSimilarityProfile,
94
+ X as buildProductSimilarityProfile,
95
+ $ as buildSimilarityQueries,
96
+ U as caughtToStreamError,
97
+ O as comparisonUiSpec,
98
+ H as createFlow,
95
99
  I as createJwtProvider,
96
- C as createToolBridge,
97
- S as createWorkerRpc,
98
- h as done,
100
+ h as createToolBridge,
101
+ B as createWorkerRpc,
102
+ T as done,
99
103
  J as elapsedMs,
100
- L as error,
101
- D as handleMainRpc,
102
- X as httpErrorToAgentError,
103
- A as invokeBeOp,
104
- g as metadata,
105
- T as mintDevJwt,
106
- F as normalizeProduct,
107
- R as nowIso,
108
- z as productDetailsUiSpec,
109
- H as productsUiSpec,
110
- _ as requestText,
111
- G as resolveFlow,
112
- x as runMainRpc,
113
- P as runTurn,
114
- $ as startWorker,
115
- V as textChunk,
116
- K as trimProductFactsCore,
117
- Q as trimProductFactsListCore,
118
- Z as uiSpec
104
+ E as error,
105
+ j as handleMainRpc,
106
+ Q as httpErrorToAgentError,
107
+ P as invokeBeOp,
108
+ ot as metadata,
109
+ F as mintDevJwt,
110
+ G as normalizeProduct,
111
+ N as normalizeSimilarityText,
112
+ M as nowIso,
113
+ Z as productDetailsUiSpec,
114
+ V as productsUiSpec,
115
+ R as rankSimilarProducts,
116
+ rt as requestText,
117
+ q as resolveFlow,
118
+ nt as runMainRpc,
119
+ x as runTurn,
120
+ Y as scoreSimilarityCandidate,
121
+ it as startWorker,
122
+ L as textChunk,
123
+ tt as tokenizeSimilarityText,
124
+ W as trimProductFactsCore,
125
+ z as trimProductFactsListCore,
126
+ m as uiSpec
119
127
  };
@@ -1,5 +1,5 @@
1
- (function(m){Object.defineProperty(m,Symbol.toStringTag,{value:"Module"});function Ee(e){return!!e&&typeof e=="object"&&e.type==="rpc.req"}function Te({worker:e,tools:t={},beacon:n,memory:r=sessionStorage}){e.addEventListener("message",o=>{const a=o.data;Ee(a)&&xe(e,a,{tools:t,beacon:n,memory:r})})}async function xe(e,t,n){try{const r=await z(t.method,t.payload,n);e.postMessage({type:"rpc.result",rpcId:t.rpcId,ok:!0,value:r})}catch(r){e.postMessage({type:"rpc.result",rpcId:t.rpcId,ok:!1,error:{message:r instanceof Error?r.message:String(r)}})}}function je(e){if(e&&typeof e=="object"&&typeof e.name=="string")return e;throw new Error("tool.invoke requires { name, input }")}function Ce(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.get requires { key }")}function Pe(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.set requires { key }")}async function z(e,t,{tools:n,beacon:r,memory:o}){if(e==="tool.invoke"){const{name:a,input:i}=je(t),s=n[a];if(typeof s!="function")throw new Error(`Unknown tool: ${a}`);return s(i)}if(e==="beacon.send")return r?.(t),{sent:!0};if(e==="memory.get"){const{key:a}=Ce(t),i=o.getItem(String(a));return i?JSON.parse(i):null}if(e==="memory.set"){const{key:a,value:i}=Pe(t);return o.setItem(String(a),JSON.stringify(i??null)),{ok:!0}}throw new Error(`Unknown RPC method: ${e}`)}function K(){return new Date().toISOString()}function x(e){return Math.max(0,Math.round(performance.now()-e))}function k(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ve(e){const{accountId:t,locale:n="en-GB",parentUrl:r="",threadId:o,incomingContext:a}=e,i=k(a)?a:{},s=k(i.thread)?i.thread:{},f=k(i.panel)?i.panel:{},p=k(i.meta)?i.meta:{},d=V(i.messages),u={id:String(o||s.id||self.crypto.randomUUID()),started_at:String(s.started_at||K()),extensions:k(s.extensions)?{...s.extensions}:{}},l=String(p.locale||n),c=String(p.parentUrl||r||typeof self<"u"&&self.location?.href||"");return{panel:{...f},messages:d,thread:u,meta:{locale:l,parentUrl:c,accountId:t}}}function Re(e,t){const n=V([t])[0];return n?{...e,messages:[...e.messages,n].slice(-50)}:e}function V(e){return Array.isArray(e)?e.map(t=>{const n=t?.role;return{role:n==="model"?"assistant":typeof n=="string"?n:"",content:String(t?.content||"")}}).filter(t=>(t.role==="user"||t.role==="assistant")&&!!t.content).slice(-50):[]}var Ie="gengage:agent:context:";async function Ue({accountId:e,threadId:t,rpc:n}){const r=await n("memory.get",{tier:"session",key:W(e,t)});return r&&typeof r=="object"&&!Array.isArray(r)?r:{}}async function Me({accountId:e,threadId:t,extensions:n,rpc:r}){await r("memory.set",{tier:"session",key:W(e,t),value:{thread:{extensions:n}}})}function W(e,t){return`${Ie}${e}:${t}`}function w(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var Y=class{#e=new Map;#t;#r;#o;#n;constructor({accountId:e,locale:t,parentUrl:n,rpc:r}){this.#t=e,this.#r=t,this.#o=n,this.#n=r}async load(e){const t=e?.meta?.threadId||e?.session_id||e?.sessionId,n=String(t||"default"),r=this.#e.get(n);if(r)return r;const o=await Ue({accountId:this.#t,threadId:n,rpc:this.#n}),a=ve({accountId:this.#t,locale:e?.locale||this.#r,parentUrl:this.#o,threadId:n,incomingContext:Oe(o,e?.context)});return this.#e.set(n,a),a}patch(e,t){const n=String(e||"default"),r=this.#e.get(n);if(!r)return null;const o=Q(r,typeof t=="function"?t(r):t);return this.#e.set(n,o),o}appendUserMessage(e,t){const n=String(e||"default");if(!t)return this.#e.get(n)??null;const r=this.#e.get(n);if(!r)return null;const o=Re(r,{role:"user",content:t});return this.#e.set(n,o),o}async commit(e){const t=String(e||"default"),n=this.#e.get(t);return n?(await Me({accountId:this.#t,threadId:t,extensions:n.thread.extensions,rpc:this.#n}),n):null}};function Oe(e,t){return!w(e)&&!w(t)?{}:Q(w(e)?e:{},w(t)?t:{})}function Q(e,t){if(!w(t))return e;const n=e,r=t,o=w(n.panel)?n.panel:{},a=w(r.panel)?r.panel:{},i=w(n.thread)?n.thread:{},s=w(r.thread)?r.thread:{},f=w(i.extensions)?i.extensions:{},p=w(s.extensions)?s.extensions:{},d=w(n.meta)?n.meta:{},u=w(r.meta)?r.meta:{};return{...e,...t,panel:{...o,...a},thread:{...i,...s,extensions:{...f,...p}},meta:{...d,...u},messages:Array.isArray(r.messages)?r.messages.slice(-50):e.messages??[]}}function X(e){const t=String.fromCharCode(...e);return btoa(t).replace(/\+/gu,"-").replace(/\//gu,"_").replace(/=+$/u,"")}function Z(e){return X(new TextEncoder().encode(JSON.stringify(e)))}async function Be({accountId:e,devJwtSecret:t,ttlS:n=300}){if(!t)throw new Error("devJwtSecret is required for local agent mode.");const r=Math.floor(Date.now()/1e3),o=`${Z({alg:"HS256",typ:"JWT"})}.${Z({sub:e,iat:r,exp:r+n,scope:"invoke",jti:crypto.randomUUID?.()||`${r}-${Math.random()}`})}`,a=await crypto.subtle.importKey("raw",new TextEncoder().encode(t),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),i=await crypto.subtle.sign("HMAC",a,new TextEncoder().encode(o));return`${o}.${X(new Uint8Array(i))}`}function ee({accountId:e,devJwtSecret:t,tokenBrokerUrl:n,tokenBrokerAudience:r,refreshSkewS:o=30,fetchImpl:a=fetch}){let i=null;return async({signal:s,parentUrl:f}={})=>{if(t)return Be({accountId:e,devJwtSecret:t});if(!n)throw new Error("tokenBrokerUrl is required for production agent mode.");const p=Math.floor(Date.now()/1e3);return i?.token&&i.expiresAtS-o>p||(i=await $e({accountId:e,tokenBrokerUrl:n,tokenBrokerAudience:r,parentUrl:f,signal:s,fetchImpl:a})),i.token}}async function $e({accountId:e,tokenBrokerUrl:t,tokenBrokerAudience:n,parentUrl:r,signal:o,fetchImpl:a}){const i=await a(t,{method:"POST",credentials:"include",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({accountId:e,scope:"invoke",audience:n||void 0,parentUrl:r||void 0}),...o?{signal:o}:{}});if(!i.ok)throw new Error(`Token broker request failed (${i.status}).`);const s=await i.json(),f=s?.token||s?.jwt||s?.access_token;if(!f||typeof f!="string")throw new Error("Token broker response did not include a JWT.");return{token:f,expiresAtS:qe(s)||De(f)||Math.floor(Date.now()/1e3)+300}}function qe(e){const t=e?.expiresAtS??e?.expires_at_s??e?.expiresInS??e?.expires_in_s;if(Number.isFinite(t))return Number(t);const n=e?.expiresIn??e?.expires_in;if(Number.isFinite(n))return Math.floor(Date.now()/1e3)+Number(n);const r=e?.expiresAt??e?.expires_at;if(typeof r=="string"){const o=Date.parse(r);if(Number.isFinite(o))return Math.floor(o/1e3)}return null}function De(e){try{const[,t]=e.split(".");if(!t)return null;const n=t.replace(/-/gu,"+").replace(/_/gu,"/"),r=atob(n.padEnd(Math.ceil(n.length/4)*4,"=")),o=JSON.parse(r);return Number.isFinite(o?.exp)?Number(o.exp):null}catch{return null}}var te={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."}},v=class extends Error{constructor(e,t,n={}){super(t),this.name="AgentError",this.code=e,this.source=n.source||"agent",n.sourceCode&&(this.sourceCode=n.sourceCode),n.detail!==void 0&&(this.detail=n.detail)}};function R(e){const t=String(e?.code||"upstream_llm"),n=te[t]||te.upstream_llm;return new v(n.code,n.message,{source:"be",sourceCode:t,detail:e?.detail})}function ne(e,t){const n=t?.error&&typeof t.error=="object"?t.error:{};return R({code:String(n.code||Le(e)),detail:n.detail})}function re(e){return e instanceof v?{type:"error",code:e.code,message:e.message}:{type:"error",code:"agent_invoke_failed",message:"The assistant could not complete that request."}}function Le(e){return e===401?"unauthorized":e===403?"forbidden":e===413?"payload_too_large":e===429?"rate_limited":"internal"}async function Ne({beUrl:e,accountId:t,devJwtSecret:n,tokenBrokerUrl:r,tokenBrokerAudience:o,jwtProvider:a,parentUrl:i,op:s,input:f,signal:p}){const d={method:"POST",headers:{authorization:`Bearer ${await(a||ee({accountId:t,devJwtSecret:n,tokenBrokerUrl:r,tokenBrokerAudience:o}))({...p?{signal:p}:{},...i?{parentUrl:i}:{}})}`,"content-type":"application/json",accept:"application/x-ndjson"},body:JSON.stringify({op:s,input:f}),...p?{signal:p}:{}},u=await fetch(`${String(e).replace(/\/+$/u,"")}/v1/invoke`,d);if(!u.ok)throw ne(u.status,await Fe(u));return Je(u)}async function Fe(e){try{return await e.json()}catch{return{error:{code:e.statusText||"internal"}}}}async function Je(e){const t=e.body?.getReader();if(!t)throw new Error("BE response body is not readable.");const n=new TextDecoder;let r="";const o={};for(;;){const{value:i,done:s}=await t.read();if(s)break;r+=n.decode(i,{stream:!0});let f=r.indexOf(`
2
- `);for(;f>=0;){const p=r.slice(0,f).trim();r=r.slice(f+1),p&&oe(JSON.parse(p),o),f=r.indexOf(`
3
- `)}}const a=r.trim();return a&&oe(JSON.parse(a),o),o}function oe(e,t){if(e._error)throw R(e._error);e._end||Object.assign(t,e)}function Ge(e={}){return{type:"metadata",...e}}function A(e,t=!1,n={}){return{type:"text_chunk",content:e,final:t,...n}}function ie(e){return{type:"ui_spec",...e}}function He(e){return{type:"action",action:e}}function ae(e,t){return{type:"error",code:e,message:t}}function I(){return{type:"done"}}function se(e,t){return e[t?.type||t?.action?.type||"inputText"]||e.inputText}async function ze({request:e,accountModule:t,contextStore:n,beClient:r,toolBridge:o,emit:a,rpc:i,signal:s}){const f=performance.now(),p=await n.load(e),d=p.thread.id,u=tt(e);n.appendUserMessage(d,u);const l=se(t.flows,e);if(!l)return a(ae("unknown_action",`No agent flow for request type ${e?.type||"inputText"}`)),a(I()),{steps:0,productSkusEmitted:[]};const c={request:e,context:n.patch(d,{})||p,bag:{},accountConfig:t.accountConfig||{},threadId:d,steps:0,productSkusEmitted:new Set,committed:!1},g={contextStore:n,beClient:r,toolBridge:o,emit:a,rpc:i,...s?{signal:s}:{}};return await U(l,c,g),c.committed||await M(c,g),await i("beacon.send",{type:"turnSummary",threadId:d,sessionId:e?.session_id||e?.sessionId||d,accountId:t.accountId||c.context.meta.accountId,steps:c.steps,totalLatencyMs:x(f),productSkusEmitted:[...c.productSkusEmitted]}),{steps:c.steps,productSkusEmitted:[...c.productSkusEmitted]}}async function U(e,t,n){for(const r of e){if(n.signal?.aborted)return;t.steps+=1,await Ke(r,t,n),t.context=n.contextStore.patch(t.threadId,{})||t.context}}async function Ke(e,t,n){const r=O(t);if(e.kind==="be_op"){await Ve(e,t,n,r);return}if(e.kind==="tool"){await We(e,t,n,r);return}if(e.kind==="emit"){Ye(e,t,n);return}if(e.kind==="branch"){await Qe(e,t,n,r);return}if(e.kind==="parallel"){await Xe(e,t,n);return}if(e.kind==="refusal"){await Ze(e,t,n,r);return}e.kind==="commit"&&await et(e,t,n)}async function Ve(e,t,n,r){const o=performance.now();let a;try{a=await n.beClient.invoke({op:e.op,input:j(e.input,r),...n.signal?{signal:n.signal}:{}})}catch(s){const f=s,p=String(f?.sourceCode||f?.code||"unknown"),d={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:x(o),errorCode:p};throw await n.rpc("beacon.send",d),s}e.out&&(t.bag[e.out]=a),ce(e,a,t,n.contextStore);const i={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:x(o)};await n.rpc("beacon.send",i)}async function We(e,t,n,r){const o=await n.toolBridge.invoke(e.name,j(e.input,r));e.out&&(t.bag[e.out]=o),ce(e,o,t,n.contextStore)}function Ye(e,t,n){const r=e.build(O(t));nt(r,t.productSkusEmitted),n.emit(r)}async function Qe(e,t,n,r){const o=String(j(e.on,r)||"default");await U(e.cases[o]||e.cases.default||[],t,n)}async function Xe(e,t,n){await Promise.all(e.steps.map(r=>U(r,t,n)))}async function Ze(e,t,n,r){n.emit(A(j(e.message,r),!0)),await M(t,n)}async function et(e,t,n){await M(t,n)}async function M(e,{contextStore:t,emit:n}){e.committed||(e.context=await t.commit(e.threadId)||e.context,e.committed=!0,n(I()))}function ce(e,t,n,r){if(typeof e.patch!="function")return;const o=e.patch(n.context,t,O(n));o&&(n.context=r.patch(n.threadId,o)||n.context)}function O(e){return{request:e.request,context:e.context,bag:e.bag,accountConfig:e.accountConfig}}function j(e,t){return typeof e=="function"?e(t):e}function tt(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}return typeof e?.action?.payload=="string"?e.action.payload:typeof e?.action?.title=="string"?e.action.title:""}function nt(e,t){const n=e,r=n.spec,o=Array.isArray(r?.items)?r.items:void 0,a=Array.isArray(n.items)?n.items:void 0,i=o||a;if(Array.isArray(i)){for(const s of i)if(s&&typeof s=="object"){const f=s.sku;typeof f=="string"&&t.add(f)}}}function rt(e){return{invoke(t,n){return e("tool.invoke",{name:t,input:n})}}}function ue({accountId:e,worker:t,beUrl:n,devJwtSecret:r,tokenBrokerUrl:o,tokenBrokerAudience:a,defaultLocale:i,tools:s={},beacon:f}){let p=1;const d=new Map;return Te({worker:t,tools:s,beacon:u=>f?.({...u,accountId:u.accountId||e}),memory:sessionStorage}),t.addEventListener("message",u=>{const l=u.data||{},c=typeof l.id=="number"?l.id:null;if(c==null)return;const g=d.get(c);if(g){if(l.type==="event"&&l.event){B(g,l.event);return}if(l.type==="error"){g.onError(new Error(l.message||"Agent worker failed")),d.delete(c);return}l.type==="end"&&d.delete(c)}}),(u,l,c)=>{const g=p++;d.set(g,l);const h=()=>{d.delete(g),t.postMessage({id:g,type:"abort"})};if(c.aborted){h();return}c.addEventListener("abort",h,{once:!0}),t.postMessage({id:g,type:"invoke",accountId:e,beUrl:n,devJwtSecret:r,tokenBrokerUrl:o,tokenBrokerAudience:a,defaultLocale:i,request:u,parentUrl:window.location.href})}}function le({accountId:e,accountModule:t,beUrl:n,devJwtSecret:r,tokenBrokerUrl:o,tokenBrokerAudience:a,defaultLocale:i,tools:s={},beacon:f}){let p=null;const d=ot({accountId:e,tools:s,beacon:f}),u=rt(d),l=ee({accountId:e,...r?{devJwtSecret:r}:{},...o?{tokenBrokerUrl:o}:{},...a?{tokenBrokerAudience:a}:{}});return async(c,g,h)=>{p||=new Y({accountId:e,locale:c?.locale||i,parentUrl:window.location.href,rpc:d});try{await ze({request:c||{},accountModule:{...t,accountId:e},contextStore:p,beClient:{invoke({op:y,input:T,signal:S}){return Ne({beUrl:n,accountId:e,jwtProvider:l,parentUrl:window.location.href,op:y,input:T,...S?{signal:S}:{}})}},toolBridge:u,emit:y=>B(g,y),rpc:d,signal:h})}catch(y){h?.aborted||(B(g,re(y)),g.onDone())}}}function ot({accountId:e,tools:t,beacon:n}){const r=o=>n?.({...o,accountId:o.accountId||e});return((o,a)=>z(o,a,{tools:t,beacon:r,memory:sessionStorage}))}function B(e,t){switch(t?.type){case"text_chunk":{const n=t;e.onTextChunk(n.content||"",n.final===!0,n);break}case"ui_spec":{const n=t;e.onUISpec(n.spec,n.widget,n.panelHint,n.clearPanel===!0);break}case"action":e.onAction(t);break;case"metadata":e.onMetadata(t);break;case"error":e.onError(it(t));break;case"done":e.onDone();break;default:break}}function it(e){const t=new Error(e.message||e.code||"Agent error");return e.code&&(t.code=e.code),t}var de="__gengageAgentFetchBridge";function at({accountId:e,streamTransport:t}){if(!e)throw new Error("accountId is required.");if(typeof t!="function")throw new Error("streamTransport is required.");const n=st(),r=`https://gengage-injector.invalid/${encodeURIComponent(e)}`,o=`${r}/chat/process_action`;return n.routes.set(o,{streamTransport:t}),{middlewareUrl:r,stop(){n.routes.delete(o)}}}function st(){const e=window,t=e[de];if(t)return t;const n=e.fetch.bind(e),r={routes:new Map,originalFetch:n};return e.fetch=(o,a)=>{const i=ct(o),s=r.routes.get(i);return s?ft(s,o,a):n(o,a)},e[de]=r,r}function ct(e){return typeof e=="string"?e:e instanceof URL?e.href:e?.url||""}function ut(e,t){if(t?.signal)return t.signal;if(typeof Request<"u"&&e instanceof Request)return e.signal}function lt(e,t){return t?.body!==void 0&&t?.body!==null?t.body:typeof Request<"u"&&e instanceof Request?e.clone().text():null}async function dt(e,t){const n=lt(e,t);if(n instanceof FormData){const o=n.get("request"),a=n.get("attachment");return{request:JSON.parse(String(o||"{}")),...a instanceof File?{attachment:a}:{}}}const r=await Promise.resolve(n);return typeof r=="string"?{request:JSON.parse(r||"{}")}:{request:{}}}function ft(e,t,n){const r=new TextEncoder,o=new AbortController,a=ut(t,n);let i=!1,s=null;const f=new ReadableStream({async start(p){const d=c=>{i||p.enqueue(r.encode(`${JSON.stringify(c)}
4
- `))},u=()=>{i||(i=!0,s?.(),p.close())},l=c=>{d({type:"error",code:c?.code||"agent_bridge_error",message:c instanceof Error?c.message:String(c)}),d({type:"done"}),u()};if(a){const c=()=>{o.abort(),i||(i=!0,s?.(),p.error(new DOMException("Aborted","AbortError")))};if(a.aborted){c();return}a.addEventListener("abort",c,{once:!0}),s=()=>a.removeEventListener("abort",c)}try{const{request:c,attachment:g}=await dt(t,n),h=e.streamTransport(c,{onTextChunk:(y,T,S={})=>d({type:"text_chunk",content:y,final:T===!0,...S}),onUISpec:(y,T,S,Dt)=>d({type:"ui_spec",spec:y,widget:T,...S?{panelHint:S}:{},...Dt?{clearPanel:!0}:{}}),onAction:y=>{d(y?.type==="action"?y:{type:"action",action:y})},onMetadata:y=>{d(y?.type==="metadata"?y:{type:"metadata",...y})},onError:l,onDone:()=>{d({type:"done"}),u()}},o.signal,g);pt(h)&&(await h,o.signal.aborted||(d({type:"done"}),u()))}catch(c){o.signal.aborted||l(c)}},cancel(){o.abort(),s?.(),i=!0}});return Promise.resolve(new Response(f,{status:200,headers:{"Content-Type":"application/x-ndjson"}}))}function pt(e){return e!==null&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function mt({accountId:e,beUrl:t,devJwtSecret:n,tokenBrokerUrl:r,tokenBrokerAudience:o,workerUrl:a,defaultLocale:i="en-GB",accountModule:s,tools:f={},beacon:p,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(!a)throw new Error("workerUrl is required.");const u=window,l=u.GengageAssistantInjector||(u.GengageAssistantInjector={}),c=l[e]||(l[e]={});if(c.agentController)return c.agentController;const g=$(a)||d?fe(a,`gengage-${e}-agent`,{allowBlobWorker:d}):null;c.streamTransport=g?ue({accountId:e,worker:g.worker,beUrl:t,...n?{devJwtSecret:n}:{},...r?{tokenBrokerUrl:r}:{},...o?{tokenBrokerAudience:o}:{},defaultLocale:i,tools:f,...p?{beacon:p}:{}}):le({accountId:e,accountModule:s,beUrl:t,...n?{devJwtSecret:n}:{},...r?{tokenBrokerUrl:r}:{},...o?{tokenBrokerAudience:o}:{},defaultLocale:i,tools:f,...p?{beacon:p}:{}});const h={type:"agent",stop(){delete c.streamTransport,g?.worker.terminate(),g?.cleanup(),delete c.agentController},diagnostics(){return{accountId:e,beUrl:t,workerUrl:a,mounted:!0,transport:g?"worker":"main-thread",flows:Object.keys(s?.flows||{})}}};return c.agentController=h,h}function $(e){const t=new URL(e,window.location.href);return t.origin===window.location.origin||t.protocol==="blob:"}function fe(e,t,n={}){const r=new URL(e,window.location.href);if($(e))return{worker:new Worker(r.href,{type:"module",name:t}),cleanup(){}};if(!n.allowBlobWorker)throw new Error("Cross-origin agent workers require allowBlobWorker=true or a same-origin workerUrl.");const o=new Blob([`import ${JSON.stringify(r.href)};
5
- `],{type:"text/javascript"}),a=URL.createObjectURL(o);try{return{worker:new Worker(a,{type:"module",name:t}),cleanup(){URL.revokeObjectURL(a)}}}catch(i){throw URL.revokeObjectURL(a),i}}function pe(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function C(e){const t=pe(e);if(!t)return null;const n=_(t.sku,t.SKU);if(!n)return null;const r={sku:n,name:_(t.name,t.title,t.short_name,n)||n,url:_(t.url)||""},o=Array.isArray(t.images)?t.images:void 0,a=_(t.imageUrl,t.image_url,t.image,o?.[0]);a&&(r.imageUrl=a),o&&o.length>1&&(r.images=o.filter(h=>!!h).map(String));const i=E(t.price_discounted),s=E(t.price),f=i||s;f>0&&(r.price=String(f));const p=i>0?s:0;p>0&&(r.originalPrice=String(p));const d=_(t.brand);d&&(r.brand=d);const u=E(t.rating);u>0&&(r.rating=u);const l=E(t.review_count)||E(t.reviewCount);l>0&&(r.reviewCount=l);const c=_(t.cart_code,t.cartCode);c&&(r.cartCode=c),typeof t.in_stock=="boolean"&&(r.inStock=t.in_stock),typeof t.inStock=="boolean"&&(r.inStock=t.inStock);const g=t.category_names;return Array.isArray(g)&&(r.categoryNames=g.map(String)),r}function me(e){const t=pe(e);if(!t)return e;const n=t.category_names,r=Array.isArray(n)?n:void 0,o=t.images,a=Array.isArray(o)?o:void 0,i={sku:t.sku,name:t.name||t.title,url:t.url,price:t.price,currency:t.price_currency||t.currency,category:r?.[r.length-1]??void 0,category_names:r?r.slice(0,4):void 0,image:a?a[0]:t.image,in_stock:t.in_stock,rating:t.rating,review_count:t.review_count};for(const s of Object.keys(i))i[s]===void 0&&delete i[s];return i}function q(e){return Array.isArray(e)?e.map(me).filter(t=>!!t):[]}function _(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function E(e){const t=Number(e);return Number.isFinite(t)?t:0}function ge(e){return Array.isArray(e)?e.map(String).filter(Boolean):typeof e=="string"&&e?[e]:[]}function ye(e=[]){const t={},n=[];return(Array.isArray(e)?e.map(C).filter(r=>!!r):[]).forEach((r,o)=>{const a=`product-${o.toString()}`;n.push(a);const i={sku:r.sku,product:r};t[a]={type:"ProductCard",props:{product:r,index:o,action:{title:r.name,type:"launchSingleProduct",payload:i}}}}),t.root={type:"ProductGrid",props:{layout:"grid"},children:n},{widget:"chat",panelHint:"panel",spec:{root:"root",elements:t}}}function gt(e){return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ProductDetailsPanel",props:{product:C(e)||e||{}}}}}}}function yt(e={}){const t=(e.multiple_product_details||e.products||[]).map(C).filter(r=>!!r),n=e.table||{};return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ComparisonTable",props:{products:t,recommended:t.find(r=>r.sku===e.recommended_choice_sku)||t[0],attributes:Object.entries(n).map(([r,o])=>({label:r,values:Array.isArray(o)?o.map(String):[String(o??"")]})),highlights:ge(e.key_differences),specialCases:ge(e.special_considerations),recommendedText:e.recommended_choice,productActions:Object.fromEntries(t.map(r=>[r.sku,{title:r.name,type:"launchSingleProduct",payload:{sku:r.sku,product:r}}]))}}}}}}function ht(e=[]){return{widget:"chat",panelHint:"inline",spec:{root:"root",elements:{root:{type:"ActionButtons",props:{buttons:(Array.isArray(e)?e:[]).map(t=>{const n=t.label||t.title||t.shortName||"",r=t.action||t.requestDetails||t.request_details;return!n||!r?.type?null:{label:n,action:{title:n,type:r.type,...r.payload!==void 0?{payload:r.payload}:{}}}}).filter(t=>!!t)}}}}}}function P(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}const n=e?.action;return n&&typeof n.payload=="string"?n.payload:n&&typeof n.title=="string"?n.title:""}function he(e){return Object.freeze([...e])}function b(e){return e&&typeof e=="object"?e:{}}function D(e){return e&&typeof e=="object"?e:{}}function we(e){return e.thread.extensions.beauty_profile}var wt=he([{kind:"be_op",op:"beauty-consulting-turn",input:({request:e,context:t})=>({utterance:P(e),prior_messages:t.messages.slice(-10),profile:we(t),candidate_products:St(e),locale:t.meta.locale}),out:"consultation",patch:be},{kind:"branch",on:({bag:e})=>b(e.consultation).consultation_state?.stage||"answer",cases:{refuse:[{kind:"refusal",message:({bag:e})=>{const t=b(e.consultation);return t.refusal?.message||t.plain_text||"I cannot help with that request."}}],needs_more_info:[{kind:"emit",build:({bag:e})=>A(N(b(e.consultation)),!0)},{kind:"commit"}],search:[{kind:"tool",name:"search",input:({request:e,bag:t,context:n})=>{const r=b(t.consultation);return{query:r.search_params?.query||P(e),facets:r.search_params?.facets||{},limit:12,locale:n.meta.locale}},out:"products",patch:(e,t)=>{const n=D(t);return{panel:{...e.panel,screen_sku_list:L(n).map(r=>bt(r)).filter(r=>!!r),last_search:{query:n.query||""}}}}},{kind:"emit",build:({bag:e})=>ie(ye(L(D(e.products))))},{kind:"be_op",op:"beauty-consulting-turn",input:({request:e,context:t,bag:n})=>({utterance:P(e),prior_messages:t.messages.slice(-10),profile:we(t),candidate_products:q(L(D(n.products)).slice(0,12)),locale:t.meta.locale}),out:"answer",patch:(e,t)=>{const n=be(e,t),r=(b(t).product_mentions||[]).map(o=>o.sku).filter(o=>!!o);return{...n||{},panel:{...e.panel,chat_mentioned_skus:r}}}},{kind:"emit",build:({bag:e})=>{const t=b(e.answer);return A(N(t),!0,{productMentions:t.product_mentions||[]})}},{kind:"commit"}],default:[{kind:"emit",build:({bag:e})=>{const t=b(e.consultation);return A(N(t),!0,{productMentions:t.product_mentions||[]})}},{kind:"commit"}]}}]);function be(e,t){const n=b(t).consultation_state?.captured_profile;if(!n)return null;const r=e.thread.extensions.beauty_profile&&typeof e.thread.extensions.beauty_profile=="object"?e.thread.extensions.beauty_profile:{};return{thread:{...e.thread,extensions:{...e.thread.extensions,beauty_profile:{...r,...n}}}}}function L(e){return Array.isArray(e?.products)?e.products:[]}function bt(e){if(e&&typeof e=="object"&&"sku"in e){const t=e.sku;if(typeof t=="string")return t}}function St(e){const t=e?.payload&&typeof e.payload=="object"?e.payload.products:void 0,n=e?.action?.payload&&typeof e.action.payload=="object"?e.action.payload.products:void 0,r=t||n;return Array.isArray(r)?q(r.slice(0,12)):void 0}function N(e){return e?.answer_html||e?.plain_text||e?.refusal?.message||"I can help with beauty shopping."}function _t(e){const t=(e?.chat||e?._chat)?.root||e?._chat?.root;return t?t.getRootNode?.()?.host||t:Array.from(document.querySelectorAll("*")).find(n=>n.shadowRoot?.querySelector?.(".gengage-chat-root, .gengage-chat-launcher-container"))}function kt(e,t){const n=_t(e);n?.style&&(t?n.style.removeProperty("display"):n.style.setProperty("display","none","important")),t||(e?.chat||e?._chat)?.close?.()}var At="nd_be_url";function Et(e,t){const n=Tt()||e.beUrl||t;if(!n)throw new Error("resolveBeUrl: backend URL is required. The injector must supply a fallback URL; the SDK has no default.");return n}function Tt(){try{const e=new URLSearchParams(window.location.search).get(At)?.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 xt="entries",jt=1,Ct={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."},Se=new Map;function F(){return Date.now()}function J(e){return e?.expiresAt!=null&&e.expiresAt<=F()}function G(e,t){return{value:e,createdAt:F(),expiresAt:t?F()+t:null}}function Pt(e,t,n){try{const r=e.getItem(`${t}${n}`);if(!r)return null;const o=JSON.parse(r);return J(o)?(e.removeItem(`${t}${n}`),null):o.value}catch{return null}}function vt(e,t,n,r,o){try{return e.setItem(`${t}${n}`,JSON.stringify(G(r,o))),!0}catch{return!1}}function Rt(e,t,n){try{e.removeItem(`${t}${n}`)}catch{}}function _e(e){try{return window[e]}catch{return null}}function ke(e,t){return e?{get:n=>Pt(e,t,n),set:(n,r,o={})=>vt(e,t,n,r,o.ttlMs),remove:n=>Rt(e,t,n)}:{get:()=>null,set:()=>!1,remove:()=>{}}}function H(e){if(Array.isArray(e))return`[${e.map(H).join(",")}]`;if(e&&typeof e=="object"){const t=e;return`{${Object.keys(t).sort().map(n=>`${JSON.stringify(n)}:${H(t[n])}`).join(",")}}`}return JSON.stringify(e)}function Ae(e){let t=2166136261;const n=H(e);for(let r=0;r<n.length;r+=1)t^=n.charCodeAt(r),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function It(e,t){const n=t.dbName||`gengage-${e}`,r=t.dbStore||xt,o=t.dbVersion||jt,a=new Map;let i=null;const s=()=>"indexedDB"in window?i||(i=new Promise(u=>{const l=indexedDB.open(n,o);l.onupgradeneeded=()=>{l.result.createObjectStore(r,{keyPath:"key"})},l.onsuccess=()=>u(l.result),l.onerror=()=>u(null),l.onblocked=()=>u(null)}),i):Promise.resolve(null);return{volatileEntries:a,idbGet:async u=>{const l=await s();return l?new Promise(c=>{const g=l.transaction(r,"readwrite").objectStore(r),h=g.get(u);h.onsuccess=()=>{const y=h.result;if(!y||J(y)){y&&g.delete(u),c(null);return}c(y.value)},h.onerror=()=>c(null)}):null},idbSet:async(u,l,c={})=>{const g=await s();return g?new Promise(h=>{const y=g.transaction(r,"readwrite");y.oncomplete=()=>h(!0),y.onerror=()=>h(!1),y.objectStore(r).put({key:u,...G(l,c.ttlMs)})}):!1},idbRemove:async u=>{const l=await s();l&&l.transaction(r,"readwrite").objectStore(r).delete(u)}}}function Ut(e,t={}){const n=window,r=n.gengage||(n.gengage={}),o=r.memory||(r.memory={}),a=o[e];if(a)return a;const i=Se.get(e)||It(e,t);Se.set(e,i);const s=t.sessionPrefix||`gengage:${e}:session:`,f=t.localPrefix||`gengage:${e}:local:`,d={get:c=>{const g=i.volatileEntries.get(c);return g?J(g)?(i.volatileEntries.delete(c),null):g.value:null},set:(c,g,h={})=>(i.volatileEntries.set(c,G(g,h.ttlMs)),!0),remove:c=>{i.volatileEntries.delete(c)},clear:()=>i.volatileEntries.clear()},u={get:i.idbGet,set:i.idbSet,remove:i.idbRemove},l={accountId:e,volatile:d,session:ke(_e("sessionStorage"),s),local:ke(_e("localStorage"),f),indexedDb:u,stableKey:Ae,policy:{...Ct,...t.policy||{}}};o[e]=l;for(const c of t.aliases||[])o[c]=l;return l}var Mt=["addToCart","search","searchKeyword","facetedSearch","searchGiftOptions","similaritySearch"];function Ot(e,t,n={}){const r=window,o=r.gengage||(r.gengage={}),a=o.tools||(o.tools={});a[e]=t;for(const i of n.accountAliases||[])a[i]=t;if(n.exposeStandardAliases!==!1)for(const i of n.standardAliases||Mt){const s=t[i];typeof s=="function"&&(a[i]=a[i]||s)}return t}function Bt({getPageType:e,getProduct:t}){return()=>({url:window.location.href,title:document.title,pageType:e(),product:t()})}function $t({accountId:e,getPageType:t,getProduct:n,getToolNames:r,getSearchCapabilities:o,getMemory:a}){return async()=>({accountId:e,url:window.location.href,pageType:t(),productSku:n()?.sku??null,toolNames:r(),...o?{searchCapabilities:o()}:{},...a?{memoryPolicy:a().policy}:{},timestamp:new Date().toISOString()})}function qt({accountId:e,runtimeFile:t="runtime.js",startExport:n="start",globalBaseUrlKey:r,errorLabel:o}={}){if(!e)throw new Error("accountId is required.");const a=o||e,i=window,s=()=>{const u=i.GengageInjectorConfig||{},l=u[e]||{};return{...u,...l}},f=()=>{const u=s();if(u.runtimeUrl)return u.runtimeUrl;const l=u.assetBaseUrl||u.baseUrl||document.currentScript?.getAttribute("src")||(r?i[r]:null);if(!l)throw new Error(`${a} runtime URL cannot be resolved.`);return new URL(t,l).href},p=i.GengageAssistantInjector||(i.GengageAssistantInjector={}),d=p[e]||(p[e]={});return d.loaderPromise||(d.loaderPromise=import(f()).then(u=>{const l=u[n];if(typeof l!="function")throw new Error(`${a} runtime export ${n} is unavailable.`);return l()}).catch(u=>{throw console.error(`[Gengage][${e}] runtime load failed`,u),u})),d.loaderPromise}m.AgentError=v,m.ContextStore=Y,m.action=He,m.actionButtonsUiSpec=ht,m.beErrorToAgentError=R,m.beautyConsultingTurnFlow=wt,m.canUseModuleWorker=$,m.caughtToStreamError=re,m.comparisonUiSpec=yt,m.createBrowserMemory=Ut,m.createDiagnosticsTool=$t,m.createFlow=he,m.createInjectorAdapter=ue,m.createMainThreadInjectorAdapter=le,m.createModuleWorker=fe,m.createReadPageTool=Bt,m.done=I,m.elapsedMs=x,m.error=ae,m.httpErrorToAgentError=ne,m.installBrowserTools=Ot,m.installFetchTransportBridge=at,m.metadata=Ge,m.mountAccount=mt,m.normalizeProduct=C,m.nowIso=K,m.productDetailsUiSpec=gt,m.productsUiSpec=ye,m.requestText=P,m.resolveBeUrl=Et,m.resolveFlow=se,m.setAssistantHostVisible=kt,m.stableKey=Ae,m.startLazyRuntimeLoader=qt,m.textChunk=A,m.trimProductFactsCore=me,m.trimProductFactsListCore=q,m.uiSpec=ie})(this.Gengage=this.Gengage||{});
1
+ (function(m){Object.defineProperty(m,Symbol.toStringTag,{value:"Module"});function Fe(e){return!!e&&typeof e=="object"&&e.type==="rpc.req"}function qe({worker:e,tools:t={},beacon:n,memory:r=sessionStorage}){e.addEventListener("message",o=>{const i=o.data;Fe(i)&&ze(e,i,{tools:t,beacon:n,memory:r})})}async function ze(e,t,n){try{const r=await te(t.method,t.payload,n);e.postMessage({type:"rpc.result",rpcId:t.rpcId,ok:!0,value:r})}catch(r){e.postMessage({type:"rpc.result",rpcId:t.rpcId,ok:!1,error:{message:r instanceof Error?r.message:String(r)}})}}function Je(e){if(e&&typeof e=="object"&&typeof e.name=="string")return e;throw new Error("tool.invoke requires { name, input }")}function Ge(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.get requires { key }")}function He(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.set requires { key }")}async function te(e,t,{tools:n,beacon:r,memory:o}){if(e==="tool.invoke"){const{name:i,input:a}=Je(t),s=n[i];if(typeof s!="function")throw new Error(`Unknown tool: ${i}`);return s(a)}if(e==="beacon.send")return r?.(t),{sent:!0};if(e==="memory.get"){const{key:i}=Ge(t),a=o.getItem(String(i));return a?JSON.parse(a):null}if(e==="memory.set"){const{key:i,value:a}=He(t);return o.setItem(String(i),JSON.stringify(a??null)),{ok:!0}}throw new Error(`Unknown RPC method: ${e}`)}function ne(){return new Date().toISOString()}function M(e){return Math.max(0,Math.round(performance.now()-e))}function C(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ke(e){const{accountId:t,locale:n="en-GB",parentUrl:r="",threadId:o,incomingContext:i}=e,a=C(i)?i:{},s=C(a.thread)?a.thread:{},p=C(a.panel)?a.panel:{},f=C(a.meta)?a.meta:{},d=re(a.messages),u={id:String(o||s.id||self.crypto.randomUUID()),started_at:String(s.started_at||ne()),extensions:C(s.extensions)?{...s.extensions}:{}},c=String(f.locale||n),l=String(f.parentUrl||r||typeof self<"u"&&self.location?.href||"");return{panel:{...p},messages:d,thread:u,meta:{locale:c,parentUrl:l,accountId:t}}}function We(e,t){const n=re([t])[0];return n?{...e,messages:[...e.messages,n].slice(-50)}:e}function re(e){return Array.isArray(e)?e.map(t=>{const n=t?.role;return{role:n==="model"?"assistant":typeof n=="string"?n:"",content:String(t?.content||"")}}).filter(t=>(t.role==="user"||t.role==="assistant")&&!!t.content).slice(-50):[]}var Ve="gengage:agent:context:";async function Qe({accountId:e,threadId:t,rpc:n}){const r=await n("memory.get",{tier:"session",key:oe(e,t)});return r&&typeof r=="object"&&!Array.isArray(r)?r:{}}async function Ye({accountId:e,threadId:t,extensions:n,rpc:r}){await r("memory.set",{tier:"session",key:oe(e,t),value:{thread:{extensions:n}}})}function oe(e,t){return`${Ve}${e}:${t}`}function S(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var ie=class{#e=new Map;#t;#r;#o;#n;constructor({accountId:e,locale:t,parentUrl:n,rpc:r}){this.#t=e,this.#r=t,this.#o=n,this.#n=r}async load(e){const t=e?.meta?.threadId||e?.session_id||e?.sessionId,n=String(t||"default"),r=this.#e.get(n);if(r)return r;const o=await Qe({accountId:this.#t,threadId:n,rpc:this.#n}),i=Ke({accountId:this.#t,locale:e?.locale||this.#r,parentUrl:this.#o,threadId:n,incomingContext:Xe(o,e?.context)});return this.#e.set(n,i),i}patch(e,t){const n=String(e||"default"),r=this.#e.get(n);if(!r)return null;const o=ae(r,typeof t=="function"?t(r):t);return this.#e.set(n,o),o}appendUserMessage(e,t){const n=String(e||"default");if(!t)return this.#e.get(n)??null;const r=this.#e.get(n);if(!r)return null;const o=We(r,{role:"user",content:t});return this.#e.set(n,o),o}async commit(e){const t=String(e||"default"),n=this.#e.get(t);return n?(await Ye({accountId:this.#t,threadId:t,extensions:n.thread.extensions,rpc:this.#n}),n):null}};function Xe(e,t){return!S(e)&&!S(t)?{}:ae(S(e)?e:{},S(t)?t:{})}function ae(e,t){if(!S(t))return e;const n=e,r=t,o=S(n.panel)?n.panel:{},i=S(r.panel)?r.panel:{},a=S(n.thread)?n.thread:{},s=S(r.thread)?r.thread:{},p=S(a.extensions)?a.extensions:{},f=S(s.extensions)?s.extensions:{},d=S(n.meta)?n.meta:{},u=S(r.meta)?r.meta:{};return{...e,...t,panel:{...o,...i},thread:{...a,...s,extensions:{...p,...f}},meta:{...d,...u},messages:Array.isArray(r.messages)?r.messages.slice(-50):e.messages??[]}}function se(e){const t=String.fromCharCode(...e);return btoa(t).replace(/\+/gu,"-").replace(/\//gu,"_").replace(/=+$/u,"")}function ce(e){return se(new TextEncoder().encode(JSON.stringify(e)))}async function Ze({accountId:e,devJwtSecret:t,ttlS:n=300}){if(!t)throw new Error("devJwtSecret is required for local agent mode.");const r=Math.floor(Date.now()/1e3),o=`${ce({alg:"HS256",typ:"JWT"})}.${ce({sub:e,iat:r,exp:r+n,scope:"invoke",jti:crypto.randomUUID?.()||`${r}-${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}.${se(new Uint8Array(a))}`}function ue({accountId:e,devJwtSecret:t,tokenBrokerUrl:n,tokenBrokerAudience:r,refreshSkewS:o=30,fetchImpl:i=fetch}){let a=null;return async({signal:s,parentUrl:p}={})=>{if(t)return Ze({accountId:e,devJwtSecret:t});if(!n)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 et({accountId:e,tokenBrokerUrl:n,tokenBrokerAudience:r,parentUrl:p,signal:s,fetchImpl:i})),a.token}}async function et({accountId:e,tokenBrokerUrl:t,tokenBrokerAudience:n,parentUrl:r,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:n||void 0,parentUrl:r||void 0}),...o?{signal:o}:{}});if(!a.ok)throw new Error(`Token broker request failed (${a.status}).`);const s=await a.json(),p=s?.token||s?.jwt||s?.access_token;if(!p||typeof p!="string")throw new Error("Token broker response did not include a JWT.");return{token:p,expiresAtS:tt(s)||nt(p)||Math.floor(Date.now()/1e3)+300}}function tt(e){const t=e?.expiresAtS??e?.expires_at_s??e?.expiresInS??e?.expires_in_s;if(Number.isFinite(t))return Number(t);const n=e?.expiresIn??e?.expires_in;if(Number.isFinite(n))return Math.floor(Date.now()/1e3)+Number(n);const r=e?.expiresAt??e?.expires_at;if(typeof r=="string"){const o=Date.parse(r);if(Number.isFinite(o))return Math.floor(o/1e3)}return null}function nt(e){try{const[,t]=e.split(".");if(!t)return null;const n=t.replace(/-/gu,"+").replace(/_/gu,"/"),r=atob(n.padEnd(Math.ceil(n.length/4)*4,"=")),o=JSON.parse(r);return Number.isFinite(o?.exp)?Number(o.exp):null}catch{return null}}var le={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."}},$=class extends Error{constructor(e,t,n={}){super(t),this.name="AgentError",this.code=e,this.source=n.source||"agent",n.sourceCode&&(this.sourceCode=n.sourceCode),n.detail!==void 0&&(this.detail=n.detail)}};function L(e){const t=String(e?.code||"upstream_llm"),n=le[t]||le.upstream_llm;return new $(n.code,n.message,{source:"be",sourceCode:t,detail:e?.detail})}function de(e,t){const n=t?.error&&typeof t.error=="object"?t.error:{};return L({code:String(n.code||rt(e)),detail:n.detail})}function fe(e){return e instanceof $?{type:"error",code:e.code,message:e.message}:{type:"error",code:"agent_invoke_failed",message:"The assistant could not complete that request."}}function rt(e){return e===401?"unauthorized":e===403?"forbidden":e===413?"payload_too_large":e===429?"rate_limited":"internal"}async function ot({beUrl:e,accountId:t,devJwtSecret:n,tokenBrokerUrl:r,tokenBrokerAudience:o,jwtProvider:i,parentUrl:a,op:s,input:p,cacheTtlS:f,signal:d}){const u={method:"POST",headers:{authorization:`Bearer ${await(i||ue({accountId:t,devJwtSecret:n,tokenBrokerUrl:r,tokenBrokerAudience:o}))({...d?{signal:d}:{},...a?{parentUrl:a}:{}})}`,"content-type":"application/json",accept:"application/x-ndjson"},body:JSON.stringify({op:s,input:p,...f!==void 0?{cache_ttl_s:f}:{}}),...d?{signal:d}:{}},c=await fetch(`${String(e).replace(/\/+$/u,"")}/v1/invoke`,u);if(!c.ok)throw de(c.status,await it(c));return at(c)}async function it(e){try{return await e.json()}catch{return{error:{code:e.statusText||"internal"}}}}async function at(e){const t=e.body?.getReader();if(!t)throw new Error("BE response body is not readable.");const n=new TextDecoder;let r="";const o={};for(;;){const{value:a,done:s}=await t.read();if(s)break;r+=n.decode(a,{stream:!0});let p=r.indexOf(`
2
+ `);for(;p>=0;){const f=r.slice(0,p).trim();r=r.slice(p+1),f&&pe(JSON.parse(f),o),p=r.indexOf(`
3
+ `)}}const i=r.trim();return i&&pe(JSON.parse(i),o),o}function pe(e,t){if(e._error)throw L(e._error);e._end||Object.assign(t,e)}function st(e={}){return{type:"metadata",...e}}function R(e,t=!1,n={}){return{type:"text_chunk",content:e,final:t,...n}}function me(e){return{type:"ui_spec",...e}}function ct(e){return{type:"action",action:e}}function ye(e,t){return{type:"error",code:e,message:t}}function D(){return{type:"done"}}function ge(e,t){return e[t?.type||t?.action?.type||"inputText"]||e.inputText}async function ut({request:e,accountModule:t,contextStore:n,beClient:r,toolBridge:o,emit:i,rpc:a,signal:s}){const p=performance.now(),f=await n.load(e),d=f.thread.id,u=wt(e);n.appendUserMessage(d,u);const c=ge(t.flows,e);if(!c)return i(ye("unknown_action",`No agent flow for request type ${e?.type||"inputText"}`)),i(D()),{steps:0,productSkusEmitted:[]};const l={request:e,context:n.patch(d,{})||f,bag:{},accountConfig:t.accountConfig||{},threadId:d,steps:0,productSkusEmitted:new Set,committed:!1},y={contextStore:n,beClient:r,toolBridge:o,emit:i,rpc:a,...s?{signal:s}:{}};return await F(c,l,y),l.committed||await q(l,y),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:M(p),productSkusEmitted:[...l.productSkusEmitted]}),{steps:l.steps,productSkusEmitted:[...l.productSkusEmitted]}}async function F(e,t,n){for(const r of e){if(n.signal?.aborted)return;t.steps+=1,await lt(r,t,n),t.context=n.contextStore.patch(t.threadId,{})||t.context}}async function lt(e,t,n){const r=z(t);if(e.kind==="be_op"){await dt(e,t,n,r);return}if(e.kind==="tool"){await ft(e,t,n,r);return}if(e.kind==="emit"){pt(e,t,n);return}if(e.kind==="branch"){await mt(e,t,n,r);return}if(e.kind==="parallel"){await yt(e,t,n);return}if(e.kind==="refusal"){await gt(e,t,n,r);return}e.kind==="commit"&&await ht(e,t,n)}async function dt(e,t,n,r){const o=performance.now();let i;const a=v(e.cacheTtlS,r);try{i=await n.beClient.invoke({op:e.op,input:v(e.input,r),...a!==void 0?{cacheTtlS:a}:{},...n.signal?{signal:n.signal}:{}})}catch(p){const f=p,d=String(f?.sourceCode||f?.code||"unknown"),u={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:M(o),errorCode:d};throw await n.rpc("beacon.send",u),p}e.out&&(t.bag[e.out]=i),he(e,i,t,n.contextStore);const s={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:M(o)};await n.rpc("beacon.send",s)}async function ft(e,t,n,r){const o=await n.toolBridge.invoke(e.name,v(e.input,r));e.out&&(t.bag[e.out]=o),he(e,o,t,n.contextStore)}function pt(e,t,n){const r=e.build(z(t));bt(r,t.productSkusEmitted),n.emit(r)}async function mt(e,t,n,r){const o=String(v(e.on,r)||"default");await F(e.cases[o]||e.cases.default||[],t,n)}async function yt(e,t,n){await Promise.all(e.steps.map(r=>F(r,t,n)))}async function gt(e,t,n,r){n.emit(R(v(e.message,r),!0)),await q(t,n)}async function ht(e,t,n){await q(t,n)}async function q(e,{contextStore:t,emit:n}){e.committed||(e.context=await t.commit(e.threadId)||e.context,e.committed=!0,n(D()))}function he(e,t,n,r){if(typeof e.patch!="function")return;const o=e.patch(n.context,t,z(n));o&&(n.context=r.patch(n.threadId,o)||n.context)}function z(e){return{request:e.request,context:e.context,bag:e.bag,accountConfig:e.accountConfig}}function v(e,t){return typeof e=="function"?e(t):e}function wt(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}return typeof e?.action?.payload=="string"?e.action.payload:typeof e?.action?.title=="string"?e.action.title:""}function bt(e,t){const n=e,r=n.spec,o=Array.isArray(r?.items)?r.items:void 0,i=Array.isArray(n.items)?n.items:void 0,a=o||i;if(Array.isArray(a)){for(const s of a)if(s&&typeof s=="object"){const p=s.sku;typeof p=="string"&&t.add(p)}}}function St(e){return{invoke(t,n){return e("tool.invoke",{name:t,input:n})}}}function we({accountId:e,worker:t,beUrl:n,devJwtSecret:r,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,tools:s={},beacon:p}){let f=1;const d=new Map;return qe({worker:t,tools:s,beacon:u=>p?.({...u,accountId:u.accountId||e}),memory:sessionStorage}),t.addEventListener("message",u=>{const c=u.data||{},l=typeof c.id=="number"?c.id:null;if(l==null)return;const y=d.get(l);if(y){if(c.type==="event"&&c.event){J(y,c.event);return}if(c.type==="error"){y.onError(new Error(c.message||"Agent worker failed")),d.delete(l);return}c.type==="end"&&d.delete(l)}}),(u,c,l,y)=>{const g=f++;d.set(g,c);const h=()=>{d.delete(g),t.postMessage({id:g,type:"abort"})},E=w=>{if(l.aborted){h();return}t.postMessage({id:g,type:"invoke",accountId:e,beUrl:n,devJwtSecret:r,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,request:w,parentUrl:window.location.href})};if(l.aborted){h();return}if(l.addEventListener("abort",h,{once:!0}),y){Se(u,y).then(E).catch(w=>{d.delete(g),c.onError(w instanceof Error?w:new Error("Failed to read image attachment"))});return}E(u)}}function be({accountId:e,accountModule:t,beUrl:n,devJwtSecret:r,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,tools:s={},beacon:p}){let f=null;const d=kt({accountId:e,tools:s,beacon:p}),u=St(d),c=ue({accountId:e,...r?{devJwtSecret:r}:{},...o?{tokenBrokerUrl:o}:{},...i?{tokenBrokerAudience:i}:{}});return async(l,y,g,h)=>{const E=await Se(l||{},h);f||=new ie({accountId:e,locale:E?.locale||a,parentUrl:window.location.href,rpc:d});try{await ut({request:E,accountModule:{...t,accountId:e},contextStore:f,beClient:{invoke({op:w,input:ee,signal:De,cacheTtlS:Sn}){return ot({beUrl:n,accountId:e,jwtProvider:c,parentUrl:window.location.href,op:w,input:ee,cacheTtlS:Sn,...De?{signal:De}:{}})}},toolBridge:u,emit:w=>J(y,w),rpc:d,signal:g})}catch(w){g?.aborted||(J(y,fe(w)),y.onDone())}}}function kt({accountId:e,tools:t,beacon:n}){const r=o=>n?.({...o,accountId:o.accountId||e});return((o,i)=>te(o,i,{tools:t,beacon:r,memory:sessionStorage}))}async function Se(e,t){if(!t||!t.type?.startsWith("image/"))return e;const n=await Tt(t),r={..._t(e.payload??e.action?.payload),image_data_url:n,image_mime:t.type};return{...e,payload:r,...e.action?{action:{...e.action,payload:r}}:{}}}function _t(e){return At(e)?{...e}:typeof e=="string"?{text:e}:{}}function At(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function Tt(e){const t=new Uint8Array(await e.arrayBuffer());let n="";const r=32768;for(let o=0;o<t.length;o+=r)n+=String.fromCharCode(...t.subarray(o,o+r));return`data:${e.type};base64,${btoa(n)}`}function J(e,t){switch(t?.type){case"text_chunk":{const n=t;e.onTextChunk(n.content||"",n.final===!0,n);break}case"ui_spec":{const n=t;e.onUISpec(n.spec,n.widget,n.panelHint,n.clearPanel===!0);break}case"action":e.onAction(t);break;case"metadata":e.onMetadata(t);break;case"error":e.onError(Et(t));break;case"done":e.onDone();break;default:break}}function Et(e){const t=new Error(e.message||e.code||"Agent error");return e.code&&(t.code=e.code),t}var ke="__gengageAgentFetchBridge";function Pt({accountId:e,streamTransport:t,endpoints:n={}}){if(!e)throw new Error("accountId is required.");if(typeof t!="function")throw new Error("streamTransport is required.");const r=jt(),o=`https://gengage-injector.invalid/${encodeURIComponent(e)}`,i=new Set,a=s=>{const p=`${o}/chat/${s}`;i.add(p);const f=n[s],d={streamTransport:t,endpoint:s};f&&(d.endpointHandler=f),r.routes.set(p,d)};a("process_action");for(const s of Object.keys(n))s!=="process_action"&&a(s);return{middlewareUrl:o,stop(){for(const s of i)r.routes.delete(s)}}}function jt(){const e=window,t=e[ke];if(t)return t;const n=e.fetch.bind(e),r={routes:new Map,originalFetch:n};return e.fetch=(o,i)=>{const a=_e(o),s=r.routes.get(a);return s?Ct(s,o,i):n(o,i)},e[ke]=r,r}function _e(e){return typeof e=="string"?e:e instanceof URL?e.href:e?.url||""}function Ae(e,t){if(t?.signal)return t.signal;if(typeof Request<"u"&&e instanceof Request)return e.signal}function Te(e,t){return t?.body!==void 0&&t?.body!==null?t.body:typeof Request<"u"&&e instanceof Request?e.clone().text():null}async function xt(e,t){const n=Te(e,t);if(n instanceof FormData){const o=n.get("request"),i=n.get("attachment");return{request:JSON.parse(String(o||"{}")),...i instanceof File?{attachment:i}:{}}}const r=await Promise.resolve(n);return typeof r=="string"?{request:JSON.parse(r||"{}")}:{request:{}}}async function Ct(e,t,n){if(e.endpoint&&e.endpoint!=="process_action"&&e.endpointHandler){const f=new AbortController,d=Ae(t,n);let u=null;if(d){const c=()=>f.abort();d.aborted&&c(),d.addEventListener("abort",c,{once:!0}),u=()=>d.removeEventListener("abort",c)}try{const c=await Rt(t,n);return await e.endpointHandler(c,{accountId:vt(t),endpoint:e.endpoint,signal:f.signal})}finally{u?.()}}const r=new TextEncoder,o=new AbortController,i=Ae(t,n);let a=!1,s=null;const p=new ReadableStream({async start(f){const d=l=>{a||f.enqueue(r.encode(`${JSON.stringify(l)}
4
+ `))},u=()=>{a||(a=!0,s?.(),f.close())},c=l=>{d({type:"error",code:l?.code||"agent_bridge_error",message:l instanceof Error?l.message:String(l)}),d({type:"done"}),u()};if(i){const l=()=>{o.abort(),a||(a=!0,s?.(),f.error(new DOMException("Aborted","AbortError")))};if(i.aborted){l();return}i.addEventListener("abort",l,{once:!0}),s=()=>i.removeEventListener("abort",l)}try{const{request:l,attachment:y}=await xt(t,n),g=e.streamTransport(l,{onTextChunk:(h,E,w={})=>d({type:"text_chunk",content:h,final:E===!0,...w}),onUISpec:(h,E,w,ee)=>d({type:"ui_spec",spec:h,widget:E,...w?{panelHint:w}:{},...ee?{clearPanel:!0}:{}}),onAction:h=>{d(h?.type==="action"?h:{type:"action",action:h})},onMetadata:h=>{d(h?.type==="metadata"?h:{type:"metadata",...h})},onError:c,onDone:()=>{d({type:"done"}),u()}},o.signal,y);It(g)&&(await g,o.signal.aborted||(d({type:"done"}),u()))}catch(l){o.signal.aborted||c(l)}},cancel(){o.abort(),s?.(),a=!0}});return new Response(p,{status:200,headers:{"Content-Type":"application/x-ndjson"}})}async function Rt(e,t){const n=await Promise.resolve(Te(e,t));return typeof n!="string"||n.trim()===""?{}:JSON.parse(n)}function vt(e){try{const[t]=new URL(_e(e)).pathname.split("/").filter(Boolean);return decodeURIComponent(t||"")}catch{return""}}function It(e){return e!==null&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Ut({accountId:e,beUrl:t,devJwtSecret:n,tokenBrokerUrl:r,tokenBrokerAudience:o,workerUrl:i,defaultLocale:a="en-GB",accountModule:s,tools:p={},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 u=window,c=u.GengageAssistantInjector||(u.GengageAssistantInjector={}),l=c[e]||(c[e]={});if(l.agentController)return l.agentController;const y=G(i)||d?Ee(i,`gengage-${e}-agent`,{allowBlobWorker:d}):null;l.streamTransport=y?we({accountId:e,worker:y.worker,beUrl:t,...n?{devJwtSecret:n}:{},...r?{tokenBrokerUrl:r}:{},...o?{tokenBrokerAudience:o}:{},defaultLocale:a,tools:p,...f?{beacon:f}:{}}):be({accountId:e,accountModule:s,beUrl:t,...n?{devJwtSecret:n}:{},...r?{tokenBrokerUrl:r}:{},...o?{tokenBrokerAudience:o}:{},defaultLocale:a,tools:p,...f?{beacon:f}:{}});const g={type:"agent",stop(){delete l.streamTransport,y?.worker.terminate(),y?.cleanup(),delete l.agentController},diagnostics(){return{accountId:e,beUrl:t,workerUrl:i,mounted:!0,transport:y?"worker":"main-thread",flows:Object.keys(s?.flows||{})}}};return l.agentController=g,g}function G(e){const t=new URL(e,window.location.href);return t.origin===window.location.origin||t.protocol==="blob:"}function Ee(e,t,n={}){const r=new URL(e,window.location.href);if(G(e))return{worker:new Worker(r.href,{type:"module",name:t}),cleanup(){}};if(!n.allowBlobWorker)throw new Error("Cross-origin agent workers require allowBlobWorker=true or a same-origin workerUrl.");const o=new Blob([`import ${JSON.stringify(r.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 Pe(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function O(e){const t=Pe(e);if(!t)return null;const n=j(t.sku,t.SKU);if(!n)return null;const r={sku:n,name:j(t.name,t.title,t.short_name,n)||n,url:j(t.url)||""},o=Array.isArray(t.images)?t.images:void 0,i=j(t.imageUrl,t.image_url,t.image,o?.[0]);i&&(r.imageUrl=i),o&&o.length>1&&(r.images=o.filter(g=>!!g).map(String));const a=I(t.price_discounted),s=I(t.price),p=a||s;p>0&&(r.price=String(p));const f=a>0?s:0;f>0&&(r.originalPrice=String(f));const d=j(t.brand);d&&(r.brand=d);const u=I(t.rating);u>0&&(r.rating=u);const c=I(t.review_count)||I(t.reviewCount);c>0&&(r.reviewCount=c);const l=j(t.cart_code,t.cartCode);l&&(r.cartCode=l),typeof t.in_stock=="boolean"&&(r.inStock=t.in_stock),typeof t.inStock=="boolean"&&(r.inStock=t.inStock);const y=t.category_names;return Array.isArray(y)&&(r.categoryNames=y.map(String)),r}function je(e){const t=Pe(e);if(!t)return e;const n=t.category_names,r=Array.isArray(n)?n: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:r?.[r.length-1]??void 0,category_names:r?r.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 s of Object.keys(a))a[s]===void 0&&delete a[s];return a}function H(e){return Array.isArray(e)?e.map(je).filter(t=>!!t):[]}function j(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function I(e){const t=Number(e);return Number.isFinite(t)?t:0}function xe(e){return Array.isArray(e)?e.map(String).filter(Boolean):typeof e=="string"&&e?[e]:[]}function Ce(e=[]){const t={},n=[];return(Array.isArray(e)?e.map(O).filter(r=>!!r):[]).forEach((r,o)=>{const i=`product-${o.toString()}`;n.push(i);const a={sku:r.sku,product:r};t[i]={type:"ProductCard",props:{product:r,index:o,action:{title:r.name,type:"launchSingleProduct",payload:a}}}}),t.root={type:"ProductGrid",props:{layout:"grid"},children:n},{widget:"chat",panelHint:"panel",spec:{root:"root",elements:t}}}function Mt(e){return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ProductDetailsPanel",props:{product:O(e)||e||{}}}}}}}function Ot(e={}){const t=(e.multiple_product_details||e.products||[]).map(O).filter(r=>!!r),n=e.table||{};return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ComparisonTable",props:{products:t,recommended:t.find(r=>r.sku===e.recommended_choice_sku)||t[0],attributes:Object.entries(n).map(([r,o])=>({label:r,values:Array.isArray(o)?o.map(String):[String(o??"")]})),highlights:xe(e.key_differences),specialCases:xe(e.special_considerations),recommendedText:e.recommended_choice,productActions:Object.fromEntries(t.map(r=>[r.sku,{title:r.name,type:"launchSingleProduct",payload:{sku:r.sku,product:r}}]))}}}}}}function Bt(e=[]){return{widget:"chat",panelHint:"inline",spec:{root:"root",elements:{root:{type:"ActionButtons",props:{buttons:(Array.isArray(e)?e:[]).map(t=>{const n=t.label||t.title||t.shortName||"",r=t.action||t.requestDetails||t.request_details;return!n||!r?.type?null:{label:n,action:{title:n,type:r.type,...r.payload!==void 0?{payload:r.payload}:{}}}}).filter(t=>!!t)}}}}}}function B(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}const n=e?.action;return n&&typeof n.payload=="string"?n.payload:n&&typeof n.title=="string"?n.title:""}function Re(e){return Object.freeze([...e])}function P(e){return e&&typeof e=="object"?e:{}}function K(e){return e&&typeof e=="object"?e:{}}function ve(e){return e.thread.extensions.beauty_profile}var Nt=Re([{kind:"be_op",op:"beauty-consulting-turn",input:({request:e,context:t})=>({utterance:B(e),prior_messages:t.messages.slice(-10),profile:ve(t),candidate_products:Lt(e),locale:t.meta.locale}),out:"consultation",patch:Ie},{kind:"branch",on:({bag:e})=>P(e.consultation).consultation_state?.stage||"answer",cases:{refuse:[{kind:"refusal",message:({bag:e})=>{const t=P(e.consultation);return t.refusal?.message||t.plain_text||"I cannot help with that request."}}],needs_more_info:[{kind:"emit",build:({bag:e})=>R(V(P(e.consultation)),!0)},{kind:"commit"}],search:[{kind:"tool",name:"search",input:({request:e,bag:t,context:n})=>{const r=P(t.consultation);return{query:r.search_params?.query||B(e),facets:r.search_params?.facets||{},limit:12,locale:n.meta.locale}},out:"products",patch:(e,t)=>{const n=K(t);return{panel:{...e.panel,screen_sku_list:W(n).map(r=>$t(r)).filter(r=>!!r),last_search:{query:n.query||""}}}}},{kind:"emit",build:({bag:e})=>me(Ce(W(K(e.products))))},{kind:"be_op",op:"beauty-consulting-turn",input:({request:e,context:t,bag:n})=>({utterance:B(e),prior_messages:t.messages.slice(-10),profile:ve(t),candidate_products:H(W(K(n.products)).slice(0,12)),locale:t.meta.locale}),out:"answer",patch:(e,t)=>{const n=Ie(e,t),r=(P(t).product_mentions||[]).map(o=>o.sku).filter(o=>!!o);return{...n||{},panel:{...e.panel,chat_mentioned_skus:r}}}},{kind:"emit",build:({bag:e})=>{const t=P(e.answer);return R(V(t),!0,{productMentions:t.product_mentions||[]})}},{kind:"commit"}],default:[{kind:"emit",build:({bag:e})=>{const t=P(e.consultation);return R(V(t),!0,{productMentions:t.product_mentions||[]})}},{kind:"commit"}]}}]);function Ie(e,t){const n=P(t).consultation_state?.captured_profile;if(!n)return null;const r=e.thread.extensions.beauty_profile&&typeof e.thread.extensions.beauty_profile=="object"?e.thread.extensions.beauty_profile:{};return{thread:{...e.thread,extensions:{...e.thread.extensions,beauty_profile:{...r,...n}}}}}function W(e){return Array.isArray(e?.products)?e.products:[]}function $t(e){if(e&&typeof e=="object"&&"sku"in e){const t=e.sku;if(typeof t=="string")return t}}function Lt(e){const t=e?.payload&&typeof e.payload=="object"?e.payload.products:void 0,n=e?.action?.payload&&typeof e.action.payload=="object"?e.action.payload.products:void 0,r=t||n;return Array.isArray(r)?H(r.slice(0,12)):void 0}function V(e){return e?.answer_html||e?.plain_text||e?.refusal?.message||"I can help with beauty shopping."}var Ue=new Set(["and","are","box","for","from","gift","gifts","interflora","the","with"]),Dt={token:.26,keyword:.22,category:.18,facet:.16,color:.08,attribute:.06,price:.08,retrieval:.08},Ft=["amber","beige","black","blue","blush","bronze","brown","cream","gold","green","grey","ivory","lilac","mixed","orange","pastel","pink","purple","red","silver","white","yellow"];function A(e){return String(e??"").normalize("NFKD").replace(new RegExp("\\p{Diacritic}","gu"),"").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function k(e,t=Ue){const n=t instanceof Set?t:new Set([...Ue,...t]),r=new Set,o=[];for(const i of A(e).split(/\s+/u))i.length<3||n.has(i)||r.has(i)||(r.add(i),o.push(i));return o}function U(e,t={}){if(Gt(e))return e;const n=t.facetKeys,r=b(e.category_names??e.category),o=b(e.category_ids),i=Ht(e.facet_hits),a=Object.entries(i).filter(([g])=>!n||n.some(h=>A(h)===A(g))).map(([,g])=>g),s=_(e.name,e.title),p=_(e.brand),f=t.sourceKeywords??[],d=[s,p,...r,...a,...b(e.promotions),_(e.description),...f].join(" "),u=k(d,t.stopWords),c=_(t.sourceProductType,Vt(r,s,u),u[0]),l=T([...Wt(d,Ft),...Object.entries(i).filter(([g])=>/colou?r/iu.test(g)).flatMap(([,g])=>k(g,t.stopWords))]),y=T([...a.flatMap(g=>k(g,t.stopWords)),...b(e.promotions).flatMap(g=>k(g,t.stopWords))]).slice(0,24);return{sku:_(e.sku),title:s,brand:p,productType:c,categoryNames:r,categoryIds:o,facets:i,keywords:T([...f.flatMap(g=>k(g,t.stopWords)),...u]).slice(0,12),tokens:u,colors:l,attributes:y,price:Kt(e)}}function qt(e,t={}){const n=_(e.product_type,e.productType),r=_(e.title,n,b(e.keywords).join(" ")),o=T([...b(e.keywords),...b(e.colors),...b(e.materials),...b(e.styles),...b(e.attributes)]);return U({sku:"__photo__",name:r,category_names:n?[n]:[],facet_hits:{colors:b(e.colors).join(", "),materials:b(e.materials).join(", "),styles:b(e.styles).join(", "),attributes:b(e.attributes).join(", ")},promotions:o},{...t,sourceProductType:n,sourceKeywords:o})}function zt(e,t={}){const n=U(e,t);return T([...t.sourceQueries??[],N([n.productType,...n.colors.slice(0,1),...n.attributes.slice(0,2)]),N([n.productType,...n.keywords.slice(0,3)]),N([n.categoryNames[n.categoryNames.length-1],...n.keywords.slice(0,2)]),N(n.title.split(/\s+/u).slice(0,6)),n.productType].map(r=>r.trim()).filter(Boolean)).slice(0,t.queryLimit??6)}function Me(e,t,n={}){const r={...Dt,...n.weights},o=U(t,n),i=[],a=x(e.tokens,o.tokens),s=x(e.keywords,o.tokens),p=Qt(e.categoryNames,o.categoryNames)||x(Oe(e.categoryNames),Oe(o.categoryNames)),f=x(e.attributes,o.attributes),d=x(e.colors,o.colors),u=x(e.attributes,o.tokens),c=Yt(e.price,o.price),l=Xt(o.sku,n.hitCounts)>0?1:0,y=Zt(e,o),g=a*r.token+s*r.keyword+p*r.category+f*r.facet+d*r.color+u*r.attribute+c*r.price+l*r.retrieval,h=en(y?g:g*.35);return y&&e.productType&&e.productType===o.productType&&i.push("same product type"),p>.4&&i.push("similar category"),f>.2&&i.push("matching product attributes"),d>0&&i.push("matching colour"),c>.8&&i.push("similar price"),y||i.push("weaker product-type match"),{score:Number(h.toFixed(4)),reasons:i}}function Jt(e,t,n={}){const r=U(e,n),o=new Set([r.sku,...n.ignoreSkus??[]].filter(Boolean));return t.filter(i=>{const a=_(i.sku);return a&&!o.has(a)}).map(i=>{const a=Me(r,i,n);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(n.limit??12,100)))}function Gt(e){return!!(e&&typeof e=="object"&&Array.isArray(e.tokens))}function _(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function b(e){return Array.isArray(e)?e.map(t=>_(t)).filter(Boolean):typeof e=="string"&&e.trim()?e.split(/[,;/|]+/u).map(t=>t.trim()).filter(Boolean):[]}function Ht(e){return!e||typeof e!="object"||Array.isArray(e)?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t,_(n)]).filter(([,t])=>t))}function Kt(e){const t=Number(e.price_discounted);if(Number.isFinite(t)&&t>0)return t;const n=Number(e.price);return Number.isFinite(n)&&n>0?n:0}function T(e){const t=new Set,n=[];for(const r of e){const o=A(r);!o||t.has(o)||(t.add(o),n.push(o))}return n}function Wt(e,t){const n=` ${A(e)} `;return t.filter(r=>n.includes(` ${A(r)} `))}function Vt(e,t,n){const r=A(e[e.length-1]??e[0]??"");if(r){const o=k(r),i=new Set(k(t));return o.find(a=>i.has(a))??o[0]??r}return n[0]??""}function N(e){return e.map(t=>A(t)).filter(Boolean).join(" ").replace(/\s+/gu," ").trim().slice(0,120)}function Oe(e){return e.flatMap(t=>k(t))}function x(e,t){const n=T(e),r=new Set(T(t));return n.length===0||r.size===0?0:n.filter(o=>r.has(o)).length/n.length}function Qt(e,t){const n=T(e),r=new Set(T(t));return n.length===0||r.size===0?0:n.filter(o=>r.has(o)).length/n.length}function Yt(e,t){return e<=0||t<=0?0:Math.min(e,t)/Math.max(e,t)}function Xt(e,t){return!e||!t?0:typeof t.get=="function"?t.get(e)??0:t[e]??0}function Zt(e,t){if(!e.productType||!t.productType||e.productType===t.productType)return!0;const n=new Set(k(e.productType)),r=new Set([...k(t.productType),...t.tokens]);return[...n].some(o=>r.has(o))}function en(e){return Math.max(0,Math.min(1,e))}function tn(e){const t=(e?.chat||e?._chat)?.root||e?._chat?.root;return t?t.getRootNode?.()?.host||t:Array.from(document.querySelectorAll("*")).find(n=>n.shadowRoot?.querySelector?.(".gengage-chat-root, .gengage-chat-launcher-container"))}function nn(e,t){const n=tn(e);n?.style&&(t?n.style.removeProperty("display"):n.style.setProperty("display","none","important")),t||(e?.chat||e?._chat)?.close?.()}var rn="nd_be_url";function on(e,t){const n=an()||e.beUrl||t;if(!n)throw new Error("resolveBeUrl: backend URL is required. The injector must supply a fallback URL; the SDK has no default.");return n}function an(){try{const e=new URLSearchParams(window.location.search).get(rn)?.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 sn="entries",cn=1,un={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 Q(){return Date.now()}function Y(e){return e?.expiresAt!=null&&e.expiresAt<=Q()}function X(e,t){return{value:e,createdAt:Q(),expiresAt:t?Q()+t:null}}function ln(e,t,n){try{const r=e.getItem(`${t}${n}`);if(!r)return null;const o=JSON.parse(r);return Y(o)?(e.removeItem(`${t}${n}`),null):o.value}catch{return null}}function dn(e,t,n,r,o){try{return e.setItem(`${t}${n}`,JSON.stringify(X(r,o))),!0}catch{return!1}}function fn(e,t,n){try{e.removeItem(`${t}${n}`)}catch{}}function Ne(e){try{return window[e]}catch{return null}}function $e(e,t){return e?{get:n=>ln(e,t,n),set:(n,r,o={})=>dn(e,t,n,r,o.ttlMs),remove:n=>fn(e,t,n)}:{get:()=>null,set:()=>!1,remove:()=>{}}}function Z(e){if(Array.isArray(e))return`[${e.map(Z).join(",")}]`;if(e&&typeof e=="object"){const t=e;return`{${Object.keys(t).sort().map(n=>`${JSON.stringify(n)}:${Z(t[n])}`).join(",")}}`}return JSON.stringify(e)}function Le(e){let t=2166136261;const n=Z(e);for(let r=0;r<n.length;r+=1)t^=n.charCodeAt(r),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function pn(e,t){const n=t.dbName||`gengage-${e}`,r=t.dbStore||sn,o=t.dbVersion||cn,i=new Map;let a=null;const s=()=>"indexedDB"in window?a||(a=new Promise(u=>{const c=indexedDB.open(n,o);c.onupgradeneeded=()=>{c.result.createObjectStore(r,{keyPath:"key"})},c.onsuccess=()=>u(c.result),c.onerror=()=>u(null),c.onblocked=()=>u(null)}),a):Promise.resolve(null);return{volatileEntries:i,idbGet:async u=>{const c=await s();return c?new Promise(l=>{const y=c.transaction(r,"readwrite").objectStore(r),g=y.get(u);g.onsuccess=()=>{const h=g.result;if(!h||Y(h)){h&&y.delete(u),l(null);return}l(h.value)},g.onerror=()=>l(null)}):null},idbSet:async(u,c,l={})=>{const y=await s();return y?new Promise(g=>{const h=y.transaction(r,"readwrite");h.oncomplete=()=>g(!0),h.onerror=()=>g(!1),h.objectStore(r).put({key:u,...X(c,l.ttlMs)})}):!1},idbRemove:async u=>{const c=await s();c&&c.transaction(r,"readwrite").objectStore(r).delete(u)}}}function mn(e,t={}){const n=window,r=n.gengage||(n.gengage={}),o=r.memory||(r.memory={}),i=o[e];if(i)return i;const a=Be.get(e)||pn(e,t);Be.set(e,a);const s=t.sessionPrefix||`gengage:${e}:session:`,p=t.localPrefix||`gengage:${e}:local:`,d={get:l=>{const y=a.volatileEntries.get(l);return y?Y(y)?(a.volatileEntries.delete(l),null):y.value:null},set:(l,y,g={})=>(a.volatileEntries.set(l,X(y,g.ttlMs)),!0),remove:l=>{a.volatileEntries.delete(l)},clear:()=>a.volatileEntries.clear()},u={get:a.idbGet,set:a.idbSet,remove:a.idbRemove},c={accountId:e,volatile:d,session:$e(Ne("sessionStorage"),s),local:$e(Ne("localStorage"),p),indexedDb:u,stableKey:Le,policy:{...un,...t.policy||{}}};o[e]=c;for(const l of t.aliases||[])o[l]=c;return c}var yn=["addToCart","search","searchKeyword","facetedSearch","searchGiftOptions","similaritySearch"];function gn(e,t,n={}){const r=window,o=r.gengage||(r.gengage={}),i=o.tools||(o.tools={});i[e]=t;for(const a of n.accountAliases||[])i[a]=t;if(n.exposeStandardAliases!==!1)for(const a of n.standardAliases||yn){const s=t[a];typeof s=="function"&&(i[a]=i[a]||s)}return t}function hn({getPageType:e,getProduct:t}){return()=>({url:window.location.href,title:document.title,pageType:e(),product:t()})}function wn({accountId:e,getPageType:t,getProduct:n,getToolNames:r,getSearchCapabilities:o,getMemory:i}){return async()=>({accountId:e,url:window.location.href,pageType:t(),productSku:n()?.sku??null,toolNames:r(),...o?{searchCapabilities:o()}:{},...i?{memoryPolicy:i().policy}:{},timestamp:new Date().toISOString()})}function bn({accountId:e,runtimeFile:t="runtime.js",startExport:n="start",globalBaseUrlKey:r,errorLabel:o}={}){if(!e)throw new Error("accountId is required.");const i=o||e,a=window,s=()=>{const u=a.GengageInjectorConfig||{},c=u[e]||{};return{...u,...c}},p=()=>{const u=s();if(u.runtimeUrl)return u.runtimeUrl;const c=u.assetBaseUrl||u.baseUrl||document.currentScript?.getAttribute("src")||(r?a[r]:null);if(!c)throw new Error(`${i} runtime URL cannot be resolved.`);return new URL(t,c).href},f=a.GengageAssistantInjector||(a.GengageAssistantInjector={}),d=f[e]||(f[e]={});return d.loaderPromise||(d.loaderPromise=import(p()).then(u=>{const c=u[n];if(typeof c!="function")throw new Error(`${i} runtime export ${n} is unavailable.`);return c()}).catch(u=>{throw console.error(`[Gengage][${e}] runtime load failed`,u),u})),d.loaderPromise}m.AgentError=$,m.ContextStore=ie,m.action=ct,m.actionButtonsUiSpec=Bt,m.beErrorToAgentError=L,m.beautyConsultingTurnFlow=Nt,m.buildPhotoSimilarityProfile=qt,m.buildProductSimilarityProfile=U,m.buildSimilarityQueries=zt,m.canUseModuleWorker=G,m.caughtToStreamError=fe,m.comparisonUiSpec=Ot,m.createBrowserMemory=mn,m.createDiagnosticsTool=wn,m.createFlow=Re,m.createInjectorAdapter=we,m.createMainThreadInjectorAdapter=be,m.createModuleWorker=Ee,m.createReadPageTool=hn,m.done=D,m.elapsedMs=M,m.error=ye,m.httpErrorToAgentError=de,m.installBrowserTools=gn,m.installFetchTransportBridge=Pt,m.metadata=st,m.mountAccount=Ut,m.normalizeProduct=O,m.normalizeSimilarityText=A,m.nowIso=ne,m.productDetailsUiSpec=Mt,m.productsUiSpec=Ce,m.rankSimilarProducts=Jt,m.requestText=B,m.resolveBeUrl=on,m.resolveFlow=ge,m.scoreSimilarityCandidate=Me,m.setAssistantHostVisible=nn,m.stableKey=Le,m.startLazyRuntimeLoader=bn,m.textChunk=R,m.tokenizeSimilarityText=k,m.trimProductFactsCore=je,m.trimProductFactsListCore=H,m.uiSpec=me})(this.Gengage=this.Gengage||{});
@@ -1,4 +1,4 @@
1
- import { i as U } from "./widget-base-B3Oq8pjs.js";
1
+ import { i as U } from "./widget-base-UJbh-z_5.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");
@@ -1,4 +1,4 @@
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-C66Wp6OR.js";
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-B-lBAc6Z.js";
2
2
  export {
3
3
  s as CHAT_SCROLL_ELEMENT_ID,
4
4
  r as ChatPresentationState,