@gengage/assistant-fe 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -22
- package/dist/agentic/adaptor/fetch-bridge.d.ts +3 -2
- package/dist/agentic/index.d.ts +1 -0
- package/dist/agentic/index.js +358 -306
- package/dist/agentic/similarity.d.ts +77 -0
- package/dist/agentic/types.d.ts +2 -0
- package/dist/agentic/util/be-url.d.ts +1 -1
- package/dist/agentic/worker/be-client.d.ts +2 -1
- package/dist/agentic/worker.d.ts +1 -0
- package/dist/agentic/worker.js +65 -57
- package/dist/agentic.iife.js +5 -5
- package/dist/{api-paths-DJFF9RuZ.js → api-paths-B1sFG4Tn.js} +1 -1
- package/dist/chat/runtime.d.ts +1 -0
- package/dist/chat-runtime.js +1 -1
- package/dist/chat.iife.js +2 -2
- package/dist/chat.js +1 -1
- package/dist/common/overlay.d.ts +1 -1
- package/dist/common/transport.d.ts +7 -0
- package/dist/{common-BydCGBNn.js → common-BML75wCP.js} +1 -1
- package/dist/common.js +5 -5
- package/dist/{connection-warning-Pbvk3J8k.js → connection-warning-Qy4APv0U.js} +1 -1
- package/dist/{fastIntent-CkYN2UOl.js → fastIntent-CXqUDc50.js} +1 -1
- package/dist/index.js +10 -10
- package/dist/native.iife.js +2 -2
- package/dist/qna/types.d.ts +1 -1
- package/dist/qna-runtime.js +1 -1
- package/dist/qna.iife.js +1 -1
- package/dist/qna.js +1 -1
- package/dist/{runtime-OpNoB3cu.js → runtime-C5FjeLrv.js} +116 -113
- package/dist/{runtime-iCLkUjI3.js → runtime-DmZ325aj.js} +3 -3
- package/dist/{runtime-DbZO1qG5.js → runtime-U8DOh3fb.js} +3 -3
- package/dist/{simbut-FyXolmZY.js → simbut-BJpWnq1J.js} +1 -1
- package/dist/simbut.iife.js +1 -1
- package/dist/simbut.js +1 -1
- package/dist/{beauty-consulting-turn-BmPXbkQg.js → similarity-DcfZ0CKT.js} +515 -295
- package/dist/{simrel-CbLe5OAr.js → simrel-B7RQY06h.js} +1 -1
- package/dist/simrel-runtime.js +1 -1
- package/dist/simrel.iife.js +1 -1
- package/dist/simrel.js +2 -2
- package/dist/{widget-base-COP8QwU3.js → widget-base-d-dDGkr7.js} +1 -1
- package/package.json +2 -34
|
@@ -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>>;
|
package/dist/agentic/types.d.ts
CHANGED
|
@@ -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 {};
|
package/dist/agentic/worker.d.ts
CHANGED
|
@@ -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';
|
package/dist/agentic/worker.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
function
|
|
3
|
-
const
|
|
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
|
-
|
|
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" && (
|
|
9
|
+
typeof r.id == "number" && (n.get(r.id)?.abort(), n.delete(r.id));
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
-
r.type === "invoke" &&
|
|
12
|
+
r.type === "invoke" && v(r);
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
|
-
async function
|
|
15
|
+
async function v(t) {
|
|
16
16
|
e = {
|
|
17
|
-
accountId: String(t.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 ||
|
|
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
|
|
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:
|
|
36
|
+
rpc: c
|
|
37
37
|
});
|
|
38
38
|
const d = new AbortController();
|
|
39
|
-
|
|
39
|
+
n.set(t.id, d);
|
|
40
40
|
const s = (o) => {
|
|
41
|
-
|
|
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,
|
|
49
|
-
await
|
|
48
|
+
const o = e, f = l;
|
|
49
|
+
await x({
|
|
50
50
|
request: t.request || {},
|
|
51
51
|
accountModule: {
|
|
52
|
-
...
|
|
52
|
+
...i,
|
|
53
53
|
accountId: o.accountId
|
|
54
54
|
},
|
|
55
55
|
contextStore: u,
|
|
56
|
-
beClient: { invoke({ op:
|
|
57
|
-
return
|
|
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:
|
|
60
|
+
jwtProvider: f,
|
|
61
61
|
parentUrl: o.parentUrl,
|
|
62
|
-
op:
|
|
63
|
-
input:
|
|
62
|
+
op: w,
|
|
63
|
+
input: y,
|
|
64
|
+
cacheTtlS: b,
|
|
64
65
|
...k ? { signal: k } : {}
|
|
65
66
|
});
|
|
66
67
|
} },
|
|
67
|
-
toolBridge:
|
|
68
|
+
toolBridge: S,
|
|
68
69
|
emit: s,
|
|
69
|
-
rpc:
|
|
70
|
+
rpc: c,
|
|
70
71
|
signal: d.signal
|
|
71
|
-
}),
|
|
72
|
+
}), a.postMessage({
|
|
72
73
|
id: t.id,
|
|
73
74
|
type: "end"
|
|
74
75
|
});
|
|
75
76
|
} catch (o) {
|
|
76
|
-
d.signal.aborted || (s(
|
|
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
|
-
|
|
82
|
+
n.delete(t.id);
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
export {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
h as createToolBridge,
|
|
101
|
+
B as createWorkerRpc,
|
|
102
|
+
T as done,
|
|
99
103
|
J as elapsedMs,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
};
|
package/dist/agentic.iife.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
(function(m){Object.defineProperty(m,Symbol.toStringTag,{value:"Module"});function
|
|
2
|
-
`);for(;
|
|
3
|
-
`)}}const
|
|
4
|
-
`))},
|
|
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 P(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(P).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:P(e)||e||{}}}}}}}function yt(e={}){const t=(e.multiple_product_details||e.products||[]).map(P).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 j(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:j(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||j(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:j(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="https://be.gengage.ai",Et="nd_be_url";function Tt(e={},t=At){return xt()||e.beUrl||t}function xt(){try{const e=new URLSearchParams(window.location.search).get(Et)?.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 Ct="entries",Pt=1,jt={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 vt(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 It(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=>vt(e,t,n),set:(n,r,o={})=>It(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 Ut(e,t){const n=t.dbName||`gengage-${e}`,r=t.dbStore||Ct,o=t.dbVersion||Pt,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 Mt(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)||Ut(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:{...jt,...t.policy||{}}};o[e]=l;for(const c of t.aliases||[])o[c]=l;return l}var Ot=["addToCart","search","searchKeyword","facetedSearch","searchGiftOptions","similaritySearch"];function Bt(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||Ot){const s=t[i];typeof s=="function"&&(a[i]=a[i]||s)}return t}function $t({getPageType:e,getProduct:t}){return()=>({url:window.location.href,title:document.title,pageType:e(),product:t()})}function qt({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 Dt({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=I,m.beautyConsultingTurnFlow=wt,m.canUseModuleWorker=$,m.caughtToStreamError=re,m.comparisonUiSpec=yt,m.createBrowserMemory=Mt,m.createDiagnosticsTool=qt,m.createFlow=he,m.createInjectorAdapter=ue,m.createMainThreadInjectorAdapter=le,m.createModuleWorker=fe,m.createReadPageTool=$t,m.done=R,m.elapsedMs=x,m.error=ae,m.httpErrorToAgentError=ne,m.installBrowserTools=Bt,m.installFetchTransportBridge=at,m.metadata=Ge,m.mountAccount=mt,m.normalizeProduct=P,m.nowIso=V,m.productDetailsUiSpec=gt,m.productsUiSpec=ye,m.requestText=j,m.resolveBeUrl=Tt,m.resolveFlow=se,m.setAssistantHostVisible=kt,m.stableKey=Ae,m.startLazyRuntimeLoader=Dt,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 $e(e){return!!e&&typeof e=="object"&&e.type==="rpc.req"}function De({worker:e,tools:t={},beacon:n,memory:r=sessionStorage}){e.addEventListener("message",o=>{const i=o.data;$e(i)&&qe(e,i,{tools:t,beacon:n,memory:r})})}async function qe(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 Fe(e){if(e&&typeof e=="object"&&typeof e.name=="string")return e;throw new Error("tool.invoke requires { name, input }")}function ze(e){if(e&&typeof e=="object"&&e.key!==void 0)return e;throw new Error("memory.get requires { key }")}function Je(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}=Fe(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}=ze(t),a=o.getItem(String(i));return a?JSON.parse(a):null}if(e==="memory.set"){const{key:i,value:a}=Je(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 x(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ge(e){const{accountId:t,locale:n="en-GB",parentUrl:r="",threadId:o,incomingContext:i}=e,a=x(i)?i:{},s=x(a.thread)?a.thread:{},p=x(a.panel)?a.panel:{},f=x(a.meta)?a.meta:{},d=re(a.messages),l={id:String(o||s.id||self.crypto.randomUUID()),started_at:String(s.started_at||ne()),extensions:x(s.extensions)?{...s.extensions}:{}},c=String(f.locale||n),u=String(f.parentUrl||r||typeof self<"u"&&self.location?.href||"");return{panel:{...p},messages:d,thread:l,meta:{locale:c,parentUrl:u,accountId:t}}}function He(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 Ke="gengage:agent:context:";async function We({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 Ve({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`${Ke}${e}:${t}`}function b(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 We({accountId:this.#t,threadId:n,rpc:this.#n}),i=Ge({accountId:this.#t,locale:e?.locale||this.#r,parentUrl:this.#o,threadId:n,incomingContext:Qe(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=He(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 Ve({accountId:this.#t,threadId:t,extensions:n.thread.extensions,rpc:this.#n}),n):null}};function Qe(e,t){return!b(e)&&!b(t)?{}:ae(b(e)?e:{},b(t)?t:{})}function ae(e,t){if(!b(t))return e;const n=e,r=t,o=b(n.panel)?n.panel:{},i=b(r.panel)?r.panel:{},a=b(n.thread)?n.thread:{},s=b(r.thread)?r.thread:{},p=b(a.extensions)?a.extensions:{},f=b(s.extensions)?s.extensions:{},d=b(n.meta)?n.meta:{},l=b(r.meta)?r.meta:{};return{...e,...t,panel:{...o,...i},thread:{...a,...s,extensions:{...p,...f}},meta:{...d,...l},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 Ye({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 Ye({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 Xe({accountId:e,tokenBrokerUrl:n,tokenBrokerAudience:r,parentUrl:p,signal:s,fetchImpl:i})),a.token}}async function Xe({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:Ze(s)||et(p)||Math.floor(Date.now()/1e3)+300}}function Ze(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 et(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."}},L=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 $(e){const t=String(e?.code||"upstream_llm"),n=le[t]||le.upstream_llm;return new L(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 $({code:String(n.code||tt(e)),detail:n.detail})}function fe(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 tt(e){return e===401?"unauthorized":e===403?"forbidden":e===413?"payload_too_large":e===429?"rate_limited":"internal"}async function nt({beUrl:e,accountId:t,devJwtSecret:n,tokenBrokerUrl:r,tokenBrokerAudience:o,jwtProvider:i,parentUrl:a,op:s,input:p,cacheTtlS:f,signal:d}){const l={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`,l);if(!c.ok)throw de(c.status,await rt(c));return ot(c)}async function rt(e){try{return await e.json()}catch{return{error:{code:e.statusText||"internal"}}}}async function ot(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 $(e._error);e._end||Object.assign(t,e)}function it(e={}){return{type:"metadata",...e}}function v(e,t=!1,n={}){return{type:"text_chunk",content:e,final:t,...n}}function me(e){return{type:"ui_spec",...e}}function at(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 st({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,l=gt(e);n.appendUserMessage(d,l);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 u={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 q(c,u,y),u.committed||await F(u,y),await a("beacon.send",{type:"turnSummary",threadId:d,sessionId:e?.session_id||e?.sessionId||d,accountId:t.accountId||u.context.meta.accountId,steps:u.steps,totalLatencyMs:M(p),productSkusEmitted:[...u.productSkusEmitted]}),{steps:u.steps,productSkusEmitted:[...u.productSkusEmitted]}}async function q(e,t,n){for(const r of e){if(n.signal?.aborted)return;t.steps+=1,await ct(r,t,n),t.context=n.contextStore.patch(t.threadId,{})||t.context}}async function ct(e,t,n){const r=z(t);if(e.kind==="be_op"){await ut(e,t,n,r);return}if(e.kind==="tool"){await lt(e,t,n,r);return}if(e.kind==="emit"){dt(e,t,n);return}if(e.kind==="branch"){await ft(e,t,n,r);return}if(e.kind==="parallel"){await pt(e,t,n);return}if(e.kind==="refusal"){await mt(e,t,n,r);return}e.kind==="commit"&&await yt(e,t,n)}async function ut(e,t,n,r){const o=performance.now();let i;const a=R(e.cacheTtlS,r);try{i=await n.beClient.invoke({op:e.op,input:R(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"),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:M(o),errorCode:d};throw await n.rpc("beacon.send",l),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 lt(e,t,n,r){const o=await n.toolBridge.invoke(e.name,R(e.input,r));e.out&&(t.bag[e.out]=o),he(e,o,t,n.contextStore)}function dt(e,t,n){const r=e.build(z(t));ht(r,t.productSkusEmitted),n.emit(r)}async function ft(e,t,n,r){const o=String(R(e.on,r)||"default");await q(e.cases[o]||e.cases.default||[],t,n)}async function pt(e,t,n){await Promise.all(e.steps.map(r=>q(r,t,n)))}async function mt(e,t,n,r){n.emit(v(R(e.message,r),!0)),await F(t,n)}async function yt(e,t,n){await F(t,n)}async function F(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 R(e,t){return typeof e=="function"?e(t):e}function gt(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 ht(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 wt(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 De({worker:t,tools:s,beacon:l=>p?.({...l,accountId:l.accountId||e}),memory:sessionStorage}),t.addEventListener("message",l=>{const c=l.data||{},u=typeof c.id=="number"?c.id:null;if(u==null)return;const y=d.get(u);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(u);return}c.type==="end"&&d.delete(u)}}),(l,c,u)=>{const y=f++;d.set(y,c);const g=()=>{d.delete(y),t.postMessage({id:y,type:"abort"})};if(u.aborted){g();return}u.addEventListener("abort",g,{once:!0}),t.postMessage({id:y,type:"invoke",accountId:e,beUrl:n,devJwtSecret:r,tokenBrokerUrl:o,tokenBrokerAudience:i,defaultLocale:a,request:l,parentUrl:window.location.href})}}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=bt({accountId:e,tools:s,beacon:p}),l=wt(d),c=ue({accountId:e,...r?{devJwtSecret:r}:{},...o?{tokenBrokerUrl:o}:{},...i?{tokenBrokerAudience:i}:{}});return async(u,y,g)=>{f||=new ie({accountId:e,locale:u?.locale||a,parentUrl:window.location.href,rpc:d});try{await st({request:u||{},accountModule:{...t,accountId:e},contextStore:f,beClient:{invoke({op:h,input:U,signal:E,cacheTtlS:ee}){return nt({beUrl:n,accountId:e,jwtProvider:c,parentUrl:window.location.href,op:h,input:U,cacheTtlS:ee,...E?{signal:E}:{}})}},toolBridge:l,emit:h=>J(y,h),rpc:d,signal:g})}catch(h){g?.aborted||(J(y,fe(h)),y.onDone())}}}function bt({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}))}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(St(t));break;case"done":e.onDone();break;default:break}}function St(e){const t=new Error(e.message||e.code||"Agent error");return e.code&&(t.code=e.code),t}var Se="__gengageAgentFetchBridge";function kt({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=_t(),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 _t(){const e=window,t=e[Se];if(t)return t;const n=e.fetch.bind(e),r={routes:new Map,originalFetch:n};return e.fetch=(o,i)=>{const a=ke(o),s=r.routes.get(a);return s?Tt(s,o,i):n(o,i)},e[Se]=r,r}function ke(e){return typeof e=="string"?e:e instanceof URL?e.href:e?.url||""}function _e(e,t){if(t?.signal)return t.signal;if(typeof Request<"u"&&e instanceof Request)return e.signal}function Ae(e,t){return t?.body!==void 0&&t?.body!==null?t.body:typeof Request<"u"&&e instanceof Request?e.clone().text():null}async function At(e,t){const n=Ae(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 Tt(e,t,n){if(e.endpoint&&e.endpoint!=="process_action"&&e.endpointHandler){const f=new AbortController,d=_e(t,n);let l=null;if(d){const c=()=>f.abort();d.aborted&&c(),d.addEventListener("abort",c,{once:!0}),l=()=>d.removeEventListener("abort",c)}try{const c=await Et(t,n);return await e.endpointHandler(c,{accountId:Pt(t),endpoint:e.endpoint,signal:f.signal})}finally{l?.()}}const r=new TextEncoder,o=new AbortController,i=_e(t,n);let a=!1,s=null;const p=new ReadableStream({async start(f){const d=u=>{a||f.enqueue(r.encode(`${JSON.stringify(u)}
|
|
4
|
+
`))},l=()=>{a||(a=!0,s?.(),f.close())},c=u=>{d({type:"error",code:u?.code||"agent_bridge_error",message:u instanceof Error?u.message:String(u)}),d({type:"done"}),l()};if(i){const u=()=>{o.abort(),a||(a=!0,s?.(),f.error(new DOMException("Aborted","AbortError")))};if(i.aborted){u();return}i.addEventListener("abort",u,{once:!0}),s=()=>i.removeEventListener("abort",u)}try{const{request:u,attachment:y}=await At(t,n),g=e.streamTransport(u,{onTextChunk:(h,U,E={})=>d({type:"text_chunk",content:h,final:U===!0,...E}),onUISpec:(h,U,E,ee)=>d({type:"ui_spec",spec:h,widget:U,...E?{panelHint:E}:{},...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"}),l()}},o.signal,y);jt(g)&&(await g,o.signal.aborted||(d({type:"done"}),l()))}catch(u){o.signal.aborted||c(u)}},cancel(){o.abort(),s?.(),a=!0}});return new Response(p,{status:200,headers:{"Content-Type":"application/x-ndjson"}})}async function Et(e,t){const n=await Promise.resolve(Ae(e,t));return typeof n!="string"||n.trim()===""?{}:JSON.parse(n)}function Pt(e){try{const[t]=new URL(ke(e)).pathname.split("/").filter(Boolean);return decodeURIComponent(t||"")}catch{return""}}function jt(e){return e!==null&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function xt({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 l=window,c=l.GengageAssistantInjector||(l.GengageAssistantInjector={}),u=c[e]||(c[e]={});if(u.agentController)return u.agentController;const y=G(i)||d?Te(i,`gengage-${e}-agent`,{allowBlobWorker:d}):null;u.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 u.streamTransport,y?.worker.terminate(),y?.cleanup(),delete u.agentController},diagnostics(){return{accountId:e,beUrl:t,workerUrl:i,mounted:!0,transport:y?"worker":"main-thread",flows:Object.keys(s?.flows||{})}}};return u.agentController=g,g}function G(e){const t=new URL(e,window.location.href);return t.origin===window.location.origin||t.protocol==="blob:"}function Te(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 Ee(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function O(e){const t=Ee(e);if(!t)return null;const n=P(t.sku,t.SKU);if(!n)return null;const r={sku:n,name:P(t.name,t.title,t.short_name,n)||n,url:P(t.url)||""},o=Array.isArray(t.images)?t.images:void 0,i=P(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=C(t.price_discounted),s=C(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=P(t.brand);d&&(r.brand=d);const l=C(t.rating);l>0&&(r.rating=l);const c=C(t.review_count)||C(t.reviewCount);c>0&&(r.reviewCount=c);const u=P(t.cart_code,t.cartCode);u&&(r.cartCode=u),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 Pe(e){const t=Ee(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(Pe).filter(t=>!!t):[]}function P(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function C(e){const t=Number(e);return Number.isFinite(t)?t:0}function je(e){return Array.isArray(e)?e.map(String).filter(Boolean):typeof e=="string"&&e?[e]:[]}function xe(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 vt(e){return{widget:"chat",panelHint:"panel",spec:{root:"root",elements:{root:{type:"ProductDetailsPanel",props:{product:O(e)||e||{}}}}}}}function Rt(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:je(e.key_differences),specialCases:je(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 Ct(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 ve(e){return Object.freeze([...e])}function T(e){return e&&typeof e=="object"?e:{}}function K(e){return e&&typeof e=="object"?e:{}}function Re(e){return e.thread.extensions.beauty_profile}var It=ve([{kind:"be_op",op:"beauty-consulting-turn",input:({request:e,context:t})=>({utterance:B(e),prior_messages:t.messages.slice(-10),profile:Re(t),candidate_products:Mt(e),locale:t.meta.locale}),out:"consultation",patch:Ce},{kind:"branch",on:({bag:e})=>T(e.consultation).consultation_state?.stage||"answer",cases:{refuse:[{kind:"refusal",message:({bag:e})=>{const t=T(e.consultation);return t.refusal?.message||t.plain_text||"I cannot help with that request."}}],needs_more_info:[{kind:"emit",build:({bag:e})=>v(V(T(e.consultation)),!0)},{kind:"commit"}],search:[{kind:"tool",name:"search",input:({request:e,bag:t,context:n})=>{const r=T(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=>Ut(r)).filter(r=>!!r),last_search:{query:n.query||""}}}}},{kind:"emit",build:({bag:e})=>me(xe(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:Re(t),candidate_products:H(W(K(n.products)).slice(0,12)),locale:t.meta.locale}),out:"answer",patch:(e,t)=>{const n=Ce(e,t),r=(T(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=T(e.answer);return v(V(t),!0,{productMentions:t.product_mentions||[]})}},{kind:"commit"}],default:[{kind:"emit",build:({bag:e})=>{const t=T(e.consultation);return v(V(t),!0,{productMentions:t.product_mentions||[]})}},{kind:"commit"}]}}]);function Ce(e,t){const n=T(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 Ut(e){if(e&&typeof e=="object"&&"sku"in e){const t=e.sku;if(typeof t=="string")return t}}function Mt(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 Ie=new Set(["and","are","box","for","from","gift","gifts","interflora","the","with"]),Ot={token:.26,keyword:.22,category:.18,facet:.16,color:.08,attribute:.06,price:.08,retrieval:.08},Bt=["amber","beige","black","blue","blush","bronze","brown","cream","gold","green","grey","ivory","lilac","mixed","orange","pastel","pink","purple","red","silver","white","yellow"];function _(e){return String(e??"").normalize("NFKD").replace(new RegExp("\\p{Diacritic}","gu"),"").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function S(e,t=Ie){const n=t instanceof Set?t:new Set([...Ie,...t]),r=new Set,o=[];for(const i of _(e).split(/\s+/u))i.length<3||n.has(i)||r.has(i)||(r.add(i),o.push(i));return o}function I(e,t={}){if(Dt(e))return e;const n=t.facetKeys,r=w(e.category_names??e.category),o=w(e.category_ids),i=qt(e.facet_hits),a=Object.entries(i).filter(([g])=>!n||n.some(h=>_(h)===_(g))).map(([,g])=>g),s=k(e.name,e.title),p=k(e.brand),f=t.sourceKeywords??[],d=[s,p,...r,...a,...w(e.promotions),k(e.description),...f].join(" "),l=S(d,t.stopWords),c=k(t.sourceProductType,Jt(r,s,l),l[0]),u=A([...zt(d,Bt),...Object.entries(i).filter(([g])=>/colou?r/iu.test(g)).flatMap(([,g])=>S(g,t.stopWords))]),y=A([...a.flatMap(g=>S(g,t.stopWords)),...w(e.promotions).flatMap(g=>S(g,t.stopWords))]).slice(0,24);return{sku:k(e.sku),title:s,brand:p,productType:c,categoryNames:r,categoryIds:o,facets:i,keywords:A([...f.flatMap(g=>S(g,t.stopWords)),...l]).slice(0,12),tokens:l,colors:u,attributes:y,price:Ft(e)}}function Nt(e,t={}){const n=k(e.product_type,e.productType),r=k(e.title,n,w(e.keywords).join(" ")),o=A([...w(e.keywords),...w(e.colors),...w(e.materials),...w(e.styles),...w(e.attributes)]);return I({sku:"__photo__",name:r,category_names:n?[n]:[],facet_hits:{colors:w(e.colors).join(", "),materials:w(e.materials).join(", "),styles:w(e.styles).join(", "),attributes:w(e.attributes).join(", ")},promotions:o},{...t,sourceProductType:n,sourceKeywords:o})}function Lt(e,t={}){const n=I(e,t);return A([...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 Ue(e,t,n={}){const r={...Ot,...n.weights},o=I(t,n),i=[],a=j(e.tokens,o.tokens),s=j(e.keywords,o.tokens),p=Gt(e.categoryNames,o.categoryNames)||j(Me(e.categoryNames),Me(o.categoryNames)),f=j(e.attributes,o.attributes),d=j(e.colors,o.colors),l=j(e.attributes,o.tokens),c=Ht(e.price,o.price),u=Kt(o.sku,n.hitCounts)>0?1:0,y=Wt(e,o),g=a*r.token+s*r.keyword+p*r.category+f*r.facet+d*r.color+l*r.attribute+c*r.price+u*r.retrieval,h=Vt(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 $t(e,t,n={}){const r=I(e,n),o=new Set([r.sku,...n.ignoreSkus??[]].filter(Boolean));return t.filter(i=>{const a=k(i.sku);return a&&!o.has(a)}).map(i=>{const a=Ue(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 Dt(e){return!!(e&&typeof e=="object"&&Array.isArray(e.tokens))}function k(...e){for(const t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function w(e){return Array.isArray(e)?e.map(t=>k(t)).filter(Boolean):typeof e=="string"&&e.trim()?e.split(/[,;/|]+/u).map(t=>t.trim()).filter(Boolean):[]}function qt(e){return!e||typeof e!="object"||Array.isArray(e)?{}:Object.fromEntries(Object.entries(e).map(([t,n])=>[t,k(n)]).filter(([,t])=>t))}function Ft(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 A(e){const t=new Set,n=[];for(const r of e){const o=_(r);!o||t.has(o)||(t.add(o),n.push(o))}return n}function zt(e,t){const n=` ${_(e)} `;return t.filter(r=>n.includes(` ${_(r)} `))}function Jt(e,t,n){const r=_(e[e.length-1]??e[0]??"");if(r){const o=S(r),i=new Set(S(t));return o.find(a=>i.has(a))??o[0]??r}return n[0]??""}function N(e){return e.map(t=>_(t)).filter(Boolean).join(" ").replace(/\s+/gu," ").trim().slice(0,120)}function Me(e){return e.flatMap(t=>S(t))}function j(e,t){const n=A(e),r=new Set(A(t));return n.length===0||r.size===0?0:n.filter(o=>r.has(o)).length/n.length}function Gt(e,t){const n=A(e),r=new Set(A(t));return n.length===0||r.size===0?0:n.filter(o=>r.has(o)).length/n.length}function Ht(e,t){return e<=0||t<=0?0:Math.min(e,t)/Math.max(e,t)}function Kt(e,t){return!e||!t?0:typeof t.get=="function"?t.get(e)??0:t[e]??0}function Wt(e,t){if(!e.productType||!t.productType||e.productType===t.productType)return!0;const n=new Set(S(e.productType)),r=new Set([...S(t.productType),...t.tokens]);return[...n].some(o=>r.has(o))}function Vt(e){return Math.max(0,Math.min(1,e))}function Qt(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 Yt(e,t){const n=Qt(e);n?.style&&(t?n.style.removeProperty("display"):n.style.setProperty("display","none","important")),t||(e?.chat||e?._chat)?.close?.()}var Xt="nd_be_url";function Zt(e,t){const n=en()||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 en(){try{const e=new URLSearchParams(window.location.search).get(Xt)?.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 tn="entries",nn=1,rn={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."},Oe=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 on(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 an(e,t,n,r,o){try{return e.setItem(`${t}${n}`,JSON.stringify(X(r,o))),!0}catch{return!1}}function sn(e,t,n){try{e.removeItem(`${t}${n}`)}catch{}}function Be(e){try{return window[e]}catch{return null}}function Ne(e,t){return e?{get:n=>on(e,t,n),set:(n,r,o={})=>an(e,t,n,r,o.ttlMs),remove:n=>sn(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 cn(e,t){const n=t.dbName||`gengage-${e}`,r=t.dbStore||tn,o=t.dbVersion||nn,i=new Map;let a=null;const s=()=>"indexedDB"in window?a||(a=new Promise(l=>{const c=indexedDB.open(n,o);c.onupgradeneeded=()=>{c.result.createObjectStore(r,{keyPath:"key"})},c.onsuccess=()=>l(c.result),c.onerror=()=>l(null),c.onblocked=()=>l(null)}),a):Promise.resolve(null);return{volatileEntries:i,idbGet:async l=>{const c=await s();return c?new Promise(u=>{const y=c.transaction(r,"readwrite").objectStore(r),g=y.get(l);g.onsuccess=()=>{const h=g.result;if(!h||Y(h)){h&&y.delete(l),u(null);return}u(h.value)},g.onerror=()=>u(null)}):null},idbSet:async(l,c,u={})=>{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:l,...X(c,u.ttlMs)})}):!1},idbRemove:async l=>{const c=await s();c&&c.transaction(r,"readwrite").objectStore(r).delete(l)}}}function un(e,t={}){const n=window,r=n.gengage||(n.gengage={}),o=r.memory||(r.memory={}),i=o[e];if(i)return i;const a=Oe.get(e)||cn(e,t);Oe.set(e,a);const s=t.sessionPrefix||`gengage:${e}:session:`,p=t.localPrefix||`gengage:${e}:local:`,d={get:u=>{const y=a.volatileEntries.get(u);return y?Y(y)?(a.volatileEntries.delete(u),null):y.value:null},set:(u,y,g={})=>(a.volatileEntries.set(u,X(y,g.ttlMs)),!0),remove:u=>{a.volatileEntries.delete(u)},clear:()=>a.volatileEntries.clear()},l={get:a.idbGet,set:a.idbSet,remove:a.idbRemove},c={accountId:e,volatile:d,session:Ne(Be("sessionStorage"),s),local:Ne(Be("localStorage"),p),indexedDb:l,stableKey:Le,policy:{...rn,...t.policy||{}}};o[e]=c;for(const u of t.aliases||[])o[u]=c;return c}var ln=["addToCart","search","searchKeyword","facetedSearch","searchGiftOptions","similaritySearch"];function dn(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||ln){const s=t[a];typeof s=="function"&&(i[a]=i[a]||s)}return t}function fn({getPageType:e,getProduct:t}){return()=>({url:window.location.href,title:document.title,pageType:e(),product:t()})}function pn({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 mn({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 l=a.GengageInjectorConfig||{},c=l[e]||{};return{...l,...c}},p=()=>{const l=s();if(l.runtimeUrl)return l.runtimeUrl;const c=l.assetBaseUrl||l.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(l=>{const c=l[n];if(typeof c!="function")throw new Error(`${i} runtime export ${n} is unavailable.`);return c()}).catch(l=>{throw console.error(`[Gengage][${e}] runtime load failed`,l),l})),d.loaderPromise}m.AgentError=L,m.ContextStore=ie,m.action=at,m.actionButtonsUiSpec=Ct,m.beErrorToAgentError=$,m.beautyConsultingTurnFlow=It,m.buildPhotoSimilarityProfile=Nt,m.buildProductSimilarityProfile=I,m.buildSimilarityQueries=Lt,m.canUseModuleWorker=G,m.caughtToStreamError=fe,m.comparisonUiSpec=Rt,m.createBrowserMemory=un,m.createDiagnosticsTool=pn,m.createFlow=ve,m.createInjectorAdapter=we,m.createMainThreadInjectorAdapter=be,m.createModuleWorker=Te,m.createReadPageTool=fn,m.done=D,m.elapsedMs=M,m.error=ye,m.httpErrorToAgentError=de,m.installBrowserTools=dn,m.installFetchTransportBridge=kt,m.metadata=it,m.mountAccount=xt,m.normalizeProduct=O,m.normalizeSimilarityText=_,m.nowIso=ne,m.productDetailsUiSpec=vt,m.productsUiSpec=xe,m.rankSimilarProducts=$t,m.requestText=B,m.resolveBeUrl=Zt,m.resolveFlow=ge,m.scoreSimilarityCandidate=Ue,m.setAssistantHostVisible=Yt,m.stableKey=Le,m.startLazyRuntimeLoader=mn,m.textChunk=v,m.tokenizeSimilarityText=S,m.trimProductFactsCore=Pe,m.trimProductFactsListCore=H,m.uiSpec=me})(this.Gengage=this.Gengage||{});
|
package/dist/chat/runtime.d.ts
CHANGED
|
@@ -152,6 +152,7 @@ export declare class GengageChat extends BaseWidget<ChatWidgetConfig> {
|
|
|
152
152
|
protected onInit(config: ChatWidgetConfig): Promise<void>;
|
|
153
153
|
protected onUpdate(context: Partial<PageContext>): void;
|
|
154
154
|
protected onShow(): void;
|
|
155
|
+
private _primeOpenPageContext;
|
|
155
156
|
protected onHide(): void;
|
|
156
157
|
private _setupLauncherAnchor;
|
|
157
158
|
syncLauncherAnchor(): void;
|
package/dist/chat-runtime.js
CHANGED
|
@@ -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-
|
|
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-C5FjeLrv.js";
|
|
2
2
|
export {
|
|
3
3
|
s as CHAT_SCROLL_ELEMENT_ID,
|
|
4
4
|
r as ChatPresentationState,
|