@gengage/assistant-fe 0.5.6 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agentic/adaptor/create-adaptor.d.ts +19 -0
- package/dist/agentic/adaptor/fetch-bridge.d.ts +11 -0
- package/dist/agentic/adaptor/mount.d.ts +38 -0
- package/dist/agentic/context/chat-context.d.ts +15 -0
- package/dist/agentic/context/context-store.d.ts +20 -0
- package/dist/agentic/context/persistence.d.ts +12 -0
- package/dist/agentic/events/builders.d.ts +10 -0
- package/dist/agentic/events/error-taxonomy.d.ts +27 -0
- package/dist/agentic/events/product-normalize.d.ts +47 -0
- package/dist/agentic/events/ui-specs.d.ts +37 -0
- package/dist/agentic/flow/beauty-consulting-turn.d.ts +1 -0
- package/dist/agentic/flow/create-flow.d.ts +2 -0
- package/dist/agentic/flow/dispatch.d.ts +3 -0
- package/dist/agentic/index.d.ts +18 -0
- package/dist/agentic/index.js +620 -0
- package/dist/agentic/types.d.ts +212 -0
- package/dist/agentic/util/assistant-host.d.ts +11 -0
- package/dist/agentic/util/be-url.d.ts +4 -0
- package/dist/agentic/util/browser-memory.d.ts +13 -0
- package/dist/agentic/util/browser-tools.d.ts +31 -0
- package/dist/agentic/util/lazy-runtime-loader.d.ts +9 -0
- package/dist/agentic/util/request-text.d.ts +3 -0
- package/dist/agentic/util/time.d.ts +2 -0
- package/dist/agentic/worker/be-client.d.ts +15 -0
- package/dist/agentic/worker/entry.d.ts +2 -0
- package/dist/agentic/worker/flow-runner.d.ts +24 -0
- package/dist/agentic/worker/jwt-mint.d.ts +21 -0
- package/dist/agentic/worker/rpc.d.ts +24 -0
- package/dist/agentic/worker/tool-bridge.d.ts +2 -0
- package/dist/agentic/worker.d.ts +16 -0
- package/dist/agentic/worker.js +119 -0
- package/dist/agentic.iife.js +5 -0
- package/dist/{api-paths-C__u2yrA.js → api-paths-DJFF9RuZ.js} +1 -1
- package/dist/beauty-consulting-turn-BmPXbkQg.js +1019 -0
- package/dist/chat/api.d.ts +17 -0
- package/dist/chat/assistant-mode.d.ts +20 -0
- package/dist/chat/attachment-utils.d.ts +9 -0
- package/dist/chat/catalog.d.ts +455 -0
- package/dist/chat/chat-presentation-state.d.ts +53 -0
- package/dist/chat/components/AIGroupingCards.d.ts +15 -0
- package/dist/chat/components/AISuggestedSearchCards.d.ts +13 -0
- package/dist/chat/components/AITopPicks.d.ts +9 -0
- package/dist/chat/components/BeautyPhotoStep.d.ts +31 -0
- package/dist/chat/components/CategoriesContainer.d.ts +11 -0
- package/dist/chat/components/ChatDrawer.d.ts +362 -0
- package/dist/chat/components/ChoicePrompter.d.ts +21 -0
- package/dist/chat/components/ComparisonTable.d.ts +66 -0
- package/dist/chat/components/ConsultingStylePicker.d.ts +40 -0
- package/dist/chat/components/FloatingComparisonButton.d.ts +7 -0
- package/dist/chat/components/FloatingLauncher.d.ts +79 -0
- package/dist/chat/components/GroundingReviewCard.d.ts +11 -0
- package/dist/chat/components/HandoffNotice.d.ts +9 -0
- package/dist/chat/components/KvkkBanner.d.ts +6 -0
- package/dist/chat/components/Launcher.d.ts +28 -0
- package/dist/chat/components/PanelRestoreCard.d.ts +4 -0
- package/dist/chat/components/PanelTopBar.d.ts +32 -0
- package/dist/chat/components/PhotoAnalysisCard.d.ts +27 -0
- package/dist/chat/components/ProductSummaryCard.d.ts +12 -0
- package/dist/chat/components/ProsAndCons.d.ts +8 -0
- package/dist/chat/components/ReviewHighlights.d.ts +16 -0
- package/dist/chat/components/actionClassifier.d.ts +12 -0
- package/dist/chat/components/product-price-layout.d.ts +17 -0
- package/dist/chat/components/productMentionLinker.d.ts +26 -0
- package/dist/chat/components/renderUISpec.d.ts +15 -0
- package/dist/chat/components/typewriter.d.ts +24 -0
- package/dist/chat/extendedModeManager.d.ts +32 -0
- package/dist/chat/features/beauty-consulting/consulting-grid.d.ts +38 -0
- package/dist/chat/features/beauty-consulting/drawer-extensions.d.ts +22 -0
- package/dist/chat/features/beauty-consulting/mode-controller.d.ts +59 -0
- package/dist/chat/features/beauty-consulting/registry.d.ts +9 -0
- package/dist/chat/features/beauty-consulting/stream-handler.d.ts +45 -0
- package/dist/chat/history-storage.d.ts +85 -0
- package/dist/chat/index.d.ts +6 -0
- package/dist/chat/kvkk.d.ts +20 -0
- package/dist/chat/locales/en.d.ts +2 -0
- package/dist/chat/locales/index.d.ts +5 -0
- package/dist/chat/locales/tr.d.ts +2 -0
- package/dist/chat/panel-manager.d.ts +142 -0
- package/dist/chat/runtime.d.ts +416 -0
- package/dist/chat/session-persistence.d.ts +73 -0
- package/dist/chat/stream-error-display.d.ts +6 -0
- package/dist/chat/types.d.ts +547 -0
- package/dist/chat/utils/chat-presentation-debug.d.ts +18 -0
- package/dist/chat/utils/get-chat-scroll-element.d.ts +10 -0
- package/dist/chat/utils/ui.d.ts +10 -0
- package/dist/chat-runtime.js +1 -1
- package/dist/chat.iife.js +12 -12
- package/dist/chat.js +1 -1
- package/dist/common/action-router.d.ts +26 -0
- package/dist/common/api-paths.d.ts +23 -0
- package/dist/common/client.d.ts +27 -0
- package/dist/common/communication-bridge.d.ts +51 -0
- package/dist/common/config-constants.d.ts +1 -0
- package/dist/common/config-schema.d.ts +54 -0
- package/dist/common/connection-warning.d.ts +8 -0
- package/dist/common/consulting-sources.d.ts +8 -0
- package/dist/common/context.d.ts +64 -0
- package/dist/common/css-escape.d.ts +1 -0
- package/dist/common/customization-factories.d.ts +59 -0
- package/dist/common/debug.d.ts +13 -0
- package/dist/common/events.d.ts +55 -0
- package/dist/common/fastIntent.d.ts +1 -0
- package/dist/common/find-similar-payload.d.ts +3 -0
- package/dist/common/ga-datalayer.d.ts +80 -0
- package/dist/common/global-error-toast.d.ts +6 -0
- package/dist/common/index.d.ts +47 -0
- package/dist/common/indexed-db.d.ts +89 -0
- package/dist/common/locale.d.ts +1 -0
- package/dist/common/native-webview.d.ts +60 -0
- package/dist/common/navigation.d.ts +1 -0
- package/dist/common/overlay.d.ts +172 -0
- package/dist/common/page-detect.d.ts +36 -0
- package/dist/common/pill-launcher.d.ts +51 -0
- package/dist/common/preflight.d.ts +13 -0
- package/dist/common/price-formatter.d.ts +35 -0
- package/dist/common/product-utils.d.ts +35 -0
- package/dist/common/protocol-adapter.d.ts +108 -0
- package/dist/common/renderer/dom.d.ts +3 -0
- package/dist/common/renderer/index.d.ts +4 -0
- package/dist/common/renderer/overrides.d.ts +23 -0
- package/dist/common/renderer/registry.d.ts +2 -0
- package/dist/common/renderer/types.d.ts +19 -0
- package/dist/common/safe-html.d.ts +22 -0
- package/dist/common/sdk-version.d.ts +3 -0
- package/dist/common/streaming.d.ts +52 -0
- package/dist/common/suggested-search-keywords.d.ts +18 -0
- package/dist/common/theme-utils.d.ts +15 -0
- package/dist/common/transport.d.ts +75 -0
- package/dist/common/tts-player.d.ts +13 -0
- package/dist/common/types.d.ts +379 -0
- package/dist/common/ui-theme.d.ts +9 -0
- package/dist/common/uuidv7.d.ts +7 -0
- package/dist/common/voice-input.d.ts +74 -0
- package/dist/common/widget-base.d.ts +82 -0
- package/dist/{common-Da3kBFv3.js → common-BydCGBNn.js} +90 -139
- package/dist/common.js +41 -41
- package/dist/{connection-warning-DuYLTTBY.js → connection-warning-Pbvk3J8k.js} +1 -1
- package/dist/{fastIntent-CSUjkiTB.js → fastIntent-CkYN2UOl.js} +199 -137
- package/dist/index.d.ts +25 -0
- package/dist/index.js +50 -50
- package/dist/native/index.d.ts +2 -0
- package/dist/{native-webview-qfjm4SHx.js → native-webview-JDC1vtde.js} +1 -1
- package/dist/native.iife.js +14 -14
- package/dist/native.js +1 -1
- package/dist/{overlay-CP5A0Hhf.js → overlay-BetAvpVZ.js} +19 -19
- package/dist/overlay.d.ts +4 -0
- package/dist/overlay.js +1 -1
- package/dist/qna/api.d.ts +23 -0
- package/dist/qna/catalog.d.ts +60 -0
- package/dist/qna/components/ButtonRow.d.ts +15 -0
- package/dist/qna/components/TextInput.d.ts +11 -0
- package/dist/qna/components/renderUISpec.d.ts +7 -0
- package/dist/qna/index.d.ts +3 -0
- package/dist/qna/locales/en.d.ts +2 -0
- package/dist/qna/locales/index.d.ts +4 -0
- package/dist/qna/locales/tr.d.ts +2 -0
- package/dist/qna/normalize-ui-specs.d.ts +15 -0
- package/dist/qna/runtime.d.ts +73 -0
- package/dist/qna/types.d.ts +98 -0
- package/dist/qna-runtime.js +1 -1
- package/dist/qna.iife.js +1 -1
- package/dist/qna.js +1 -1
- package/dist/{runtime-CAg_iN6a.js → runtime-DbZO1qG5.js} +3 -3
- package/dist/{runtime-CFHFFIU0.js → runtime-OpNoB3cu.js} +895 -854
- package/dist/{runtime-vEZ7Jp50.js → runtime-iCLkUjI3.js} +3 -3
- package/dist/simbut/index.d.ts +31 -0
- package/dist/simbut/locales.d.ts +3 -0
- package/dist/simbut/types.d.ts +43 -0
- package/dist/{simbut-BzxDRoSM.js → simbut-FyXolmZY.js} +1 -1
- package/dist/simbut.iife.js +1 -1
- package/dist/simbut.js +1 -1
- package/dist/simrel/api.d.ts +25 -0
- package/dist/simrel/catalog.d.ts +77 -0
- package/dist/simrel/components/GroupTabs.d.ts +24 -0
- package/dist/simrel/components/ProductCard.d.ts +19 -0
- package/dist/simrel/components/ProductGrid.d.ts +17 -0
- package/dist/simrel/components/renderUISpec.d.ts +7 -0
- package/dist/simrel/index.d.ts +5 -0
- package/dist/simrel/locales/en.d.ts +2 -0
- package/dist/simrel/locales/index.d.ts +4 -0
- package/dist/simrel/locales/tr.d.ts +2 -0
- package/dist/simrel/renderers/default.d.ts +41 -0
- package/dist/simrel/runtime.d.ts +68 -0
- package/dist/simrel/types.d.ts +145 -0
- package/dist/{simrel-DsIquEK2.js → simrel-CbLe5OAr.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-DMiOpmY5.js → widget-base-COP8QwU3.js} +1 -1
- package/package.json +20 -6
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import type { ProcessActionRequest } from '../common/transport.js';
|
|
2
|
+
import type { StreamEvent, UISpec } from '../common/types.js';
|
|
3
|
+
export interface ChatThread {
|
|
4
|
+
id: string;
|
|
5
|
+
started_at: string;
|
|
6
|
+
extensions: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export type ChatPanel = Record<string, unknown>;
|
|
9
|
+
export interface ChatMessage {
|
|
10
|
+
role: 'user' | 'assistant';
|
|
11
|
+
content: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ChatMeta {
|
|
14
|
+
locale: string;
|
|
15
|
+
parentUrl: string;
|
|
16
|
+
accountId: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ChatContext {
|
|
19
|
+
panel: ChatPanel;
|
|
20
|
+
messages: ChatMessage[];
|
|
21
|
+
thread: ChatThread;
|
|
22
|
+
meta: ChatMeta;
|
|
23
|
+
}
|
|
24
|
+
export type RpcMethod = 'tool.invoke' | 'beacon.send' | 'memory.get' | 'memory.set' | (string & {});
|
|
25
|
+
export type RpcFn = <T = unknown>(method: RpcMethod, payload?: unknown, transfer?: Transferable[]) => Promise<T>;
|
|
26
|
+
export interface ToolBridge {
|
|
27
|
+
invoke<T = unknown>(name: string, input?: unknown): Promise<T>;
|
|
28
|
+
}
|
|
29
|
+
export interface BeClient {
|
|
30
|
+
invoke(args: {
|
|
31
|
+
op: string;
|
|
32
|
+
input?: unknown;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
}): Promise<unknown>;
|
|
35
|
+
}
|
|
36
|
+
export interface FlowStepCtx {
|
|
37
|
+
request: ProcessActionRequest;
|
|
38
|
+
context: ChatContext;
|
|
39
|
+
bag: Record<string, unknown>;
|
|
40
|
+
accountConfig: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
export type FlowValue<T> = T | ((ctx: FlowStepCtx) => T);
|
|
43
|
+
export type FlowPatch = (ctx: ChatContext, result: unknown, snapshot: FlowStepCtx) => Partial<ChatContext> | null | undefined;
|
|
44
|
+
export interface BeOpStep {
|
|
45
|
+
kind: 'be_op';
|
|
46
|
+
op: string;
|
|
47
|
+
input: FlowValue<unknown>;
|
|
48
|
+
out?: string;
|
|
49
|
+
patch?: FlowPatch;
|
|
50
|
+
}
|
|
51
|
+
export interface ToolStep {
|
|
52
|
+
kind: 'tool';
|
|
53
|
+
name: string;
|
|
54
|
+
input: FlowValue<unknown>;
|
|
55
|
+
out?: string;
|
|
56
|
+
patch?: FlowPatch;
|
|
57
|
+
}
|
|
58
|
+
export interface EmitStep {
|
|
59
|
+
kind: 'emit';
|
|
60
|
+
build: (ctx: FlowStepCtx) => StreamEvent;
|
|
61
|
+
}
|
|
62
|
+
export interface BranchStep {
|
|
63
|
+
kind: 'branch';
|
|
64
|
+
on: FlowValue<string | undefined>;
|
|
65
|
+
cases: Record<string, readonly FlowStep[]>;
|
|
66
|
+
}
|
|
67
|
+
export interface ParallelStep {
|
|
68
|
+
kind: 'parallel';
|
|
69
|
+
steps: readonly (readonly FlowStep[])[];
|
|
70
|
+
}
|
|
71
|
+
export interface RefusalStep {
|
|
72
|
+
kind: 'refusal';
|
|
73
|
+
message: FlowValue<string>;
|
|
74
|
+
}
|
|
75
|
+
export interface CommitStep {
|
|
76
|
+
kind: 'commit';
|
|
77
|
+
}
|
|
78
|
+
export type FlowStep = BeOpStep | ToolStep | EmitStep | BranchStep | ParallelStep | RefusalStep | CommitStep;
|
|
79
|
+
export type Flow = readonly FlowStep[];
|
|
80
|
+
export type ToolFn = (input: unknown) => unknown | Promise<unknown>;
|
|
81
|
+
export type ToolMap = Record<string, ToolFn>;
|
|
82
|
+
export interface AccountModule {
|
|
83
|
+
accountId?: string;
|
|
84
|
+
defaultLocale?: string;
|
|
85
|
+
flows: Record<string, Flow>;
|
|
86
|
+
tools?: ToolMap;
|
|
87
|
+
accountConfig?: Record<string, unknown>;
|
|
88
|
+
}
|
|
89
|
+
export interface AgentOpBeacon {
|
|
90
|
+
type: 'agentOp';
|
|
91
|
+
threadId: string;
|
|
92
|
+
sessionId: string;
|
|
93
|
+
accountId: string;
|
|
94
|
+
op: string;
|
|
95
|
+
status: 'ok' | 'error';
|
|
96
|
+
latencyMs: number;
|
|
97
|
+
errorCode?: string | undefined;
|
|
98
|
+
}
|
|
99
|
+
export interface TurnSummaryBeacon {
|
|
100
|
+
type: 'turnSummary';
|
|
101
|
+
threadId: string;
|
|
102
|
+
sessionId: string;
|
|
103
|
+
accountId: string;
|
|
104
|
+
steps: number;
|
|
105
|
+
totalLatencyMs: number;
|
|
106
|
+
productSkusEmitted: string[];
|
|
107
|
+
}
|
|
108
|
+
export interface GenericBeacon {
|
|
109
|
+
type: string;
|
|
110
|
+
accountId?: string;
|
|
111
|
+
[key: string]: unknown;
|
|
112
|
+
}
|
|
113
|
+
export type AgentBeaconPayload = AgentOpBeacon | TurnSummaryBeacon | GenericBeacon;
|
|
114
|
+
export type BeaconCallback = (payload: AgentBeaconPayload) => void;
|
|
115
|
+
export interface UiSpecEnvelope {
|
|
116
|
+
widget: 'chat' | 'qna' | 'simrel';
|
|
117
|
+
spec: UISpec;
|
|
118
|
+
panelHint?: 'panel' | 'inline';
|
|
119
|
+
clearPanel?: true;
|
|
120
|
+
}
|
|
121
|
+
export interface MemoryBucketSync {
|
|
122
|
+
get: (key: string) => unknown;
|
|
123
|
+
set: (key: string, value: unknown, options?: {
|
|
124
|
+
ttlMs?: number;
|
|
125
|
+
}) => boolean;
|
|
126
|
+
remove: (key: string) => void;
|
|
127
|
+
clear?: () => void;
|
|
128
|
+
}
|
|
129
|
+
export interface MemoryBucketAsync {
|
|
130
|
+
get: (key: string) => Promise<unknown>;
|
|
131
|
+
set: (key: string, value: unknown, options?: {
|
|
132
|
+
ttlMs?: number;
|
|
133
|
+
}) => Promise<boolean>;
|
|
134
|
+
remove: (key: string) => Promise<void>;
|
|
135
|
+
}
|
|
136
|
+
export interface BrowserMemory {
|
|
137
|
+
accountId: string;
|
|
138
|
+
volatile: MemoryBucketSync & {
|
|
139
|
+
clear: () => void;
|
|
140
|
+
};
|
|
141
|
+
session: MemoryBucketSync;
|
|
142
|
+
local: MemoryBucketSync;
|
|
143
|
+
indexedDb: MemoryBucketAsync;
|
|
144
|
+
stableKey: (value: unknown) => string;
|
|
145
|
+
policy: Record<string, string>;
|
|
146
|
+
}
|
|
147
|
+
export interface WorkerInvokeMessage {
|
|
148
|
+
id: number;
|
|
149
|
+
type: 'invoke';
|
|
150
|
+
accountId?: string;
|
|
151
|
+
beUrl?: string;
|
|
152
|
+
devJwtSecret?: string;
|
|
153
|
+
tokenBrokerUrl?: string;
|
|
154
|
+
tokenBrokerAudience?: string;
|
|
155
|
+
defaultLocale?: string;
|
|
156
|
+
request: ProcessActionRequest;
|
|
157
|
+
parentUrl?: string;
|
|
158
|
+
}
|
|
159
|
+
export interface WorkerAbortMessage {
|
|
160
|
+
id: number;
|
|
161
|
+
type: 'abort';
|
|
162
|
+
}
|
|
163
|
+
export type WorkerInboundMessage = WorkerInvokeMessage | WorkerAbortMessage;
|
|
164
|
+
export interface WorkerEventOutbound {
|
|
165
|
+
id: number;
|
|
166
|
+
type: 'event';
|
|
167
|
+
event: StreamEvent;
|
|
168
|
+
}
|
|
169
|
+
export interface WorkerEndOutbound {
|
|
170
|
+
id: number;
|
|
171
|
+
type: 'end';
|
|
172
|
+
}
|
|
173
|
+
export interface WorkerErrorOutbound {
|
|
174
|
+
id: number;
|
|
175
|
+
type: 'error';
|
|
176
|
+
message?: string;
|
|
177
|
+
}
|
|
178
|
+
export type WorkerOutboundMessage = WorkerEventOutbound | WorkerEndOutbound | WorkerErrorOutbound;
|
|
179
|
+
export interface RpcRequestMessage {
|
|
180
|
+
type: 'rpc.req';
|
|
181
|
+
rpcId: number;
|
|
182
|
+
method: string;
|
|
183
|
+
payload?: unknown;
|
|
184
|
+
}
|
|
185
|
+
export interface RpcResultMessage {
|
|
186
|
+
type: 'rpc.result';
|
|
187
|
+
rpcId: number;
|
|
188
|
+
ok: boolean;
|
|
189
|
+
value?: unknown;
|
|
190
|
+
error?: {
|
|
191
|
+
message?: string;
|
|
192
|
+
} | string;
|
|
193
|
+
}
|
|
194
|
+
export interface BeautyConsultingResult {
|
|
195
|
+
consultation_state?: {
|
|
196
|
+
stage?: string;
|
|
197
|
+
captured_profile?: Record<string, unknown>;
|
|
198
|
+
};
|
|
199
|
+
refusal?: {
|
|
200
|
+
message?: string;
|
|
201
|
+
};
|
|
202
|
+
plain_text?: string;
|
|
203
|
+
answer_html?: string;
|
|
204
|
+
product_mentions?: Array<{
|
|
205
|
+
sku: string;
|
|
206
|
+
short_name?: string;
|
|
207
|
+
}>;
|
|
208
|
+
search_params?: {
|
|
209
|
+
query?: string;
|
|
210
|
+
facets?: Record<string, unknown>;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface ChatLike {
|
|
2
|
+
root?: Element | null;
|
|
3
|
+
close?: () => void;
|
|
4
|
+
}
|
|
5
|
+
interface AssistantController {
|
|
6
|
+
chat?: ChatLike;
|
|
7
|
+
_chat?: ChatLike;
|
|
8
|
+
}
|
|
9
|
+
export declare function getAssistantHost(controller: AssistantController | null | undefined): HTMLElement | undefined;
|
|
10
|
+
export declare function setAssistantHostVisible(controller: AssistantController | null | undefined, visible: boolean): void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BrowserMemory } from '../types.js';
|
|
2
|
+
interface BrowserMemoryOptions {
|
|
3
|
+
dbName?: string;
|
|
4
|
+
dbStore?: string;
|
|
5
|
+
dbVersion?: number;
|
|
6
|
+
sessionPrefix?: string;
|
|
7
|
+
localPrefix?: string;
|
|
8
|
+
policy?: Record<string, string>;
|
|
9
|
+
aliases?: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function stableKey(value: unknown): string;
|
|
12
|
+
export declare function createBrowserMemory(accountId: string, options?: BrowserMemoryOptions): BrowserMemory;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { BrowserMemory, ToolMap } from '../types.js';
|
|
2
|
+
interface InstallToolsOptions {
|
|
3
|
+
accountAliases?: string[];
|
|
4
|
+
exposeStandardAliases?: boolean;
|
|
5
|
+
standardAliases?: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function installBrowserTools(accountId: string, tools: ToolMap, options?: InstallToolsOptions): ToolMap;
|
|
8
|
+
interface PageProductLike {
|
|
9
|
+
sku?: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
interface ReadPageToolDeps {
|
|
13
|
+
getPageType: () => string;
|
|
14
|
+
getProduct: () => PageProductLike | null | undefined;
|
|
15
|
+
}
|
|
16
|
+
export declare function createReadPageTool({ getPageType, getProduct }: ReadPageToolDeps): () => {
|
|
17
|
+
url: string;
|
|
18
|
+
title: string;
|
|
19
|
+
pageType: string;
|
|
20
|
+
product: PageProductLike | null | undefined;
|
|
21
|
+
};
|
|
22
|
+
interface DiagnosticsToolDeps {
|
|
23
|
+
accountId: string;
|
|
24
|
+
getPageType: () => string;
|
|
25
|
+
getProduct: () => PageProductLike | null | undefined;
|
|
26
|
+
getToolNames: () => string[];
|
|
27
|
+
getSearchCapabilities?: () => unknown;
|
|
28
|
+
getMemory?: () => BrowserMemory;
|
|
29
|
+
}
|
|
30
|
+
export declare function createDiagnosticsTool({ accountId, getPageType, getProduct, getToolNames, getSearchCapabilities, getMemory, }: DiagnosticsToolDeps): () => Promise<Record<string, unknown>>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface LazyRuntimeLoaderOptions {
|
|
2
|
+
accountId: string;
|
|
3
|
+
runtimeFile?: string;
|
|
4
|
+
startExport?: string;
|
|
5
|
+
globalBaseUrlKey?: string;
|
|
6
|
+
errorLabel?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function startLazyRuntimeLoader({ accountId, runtimeFile, startExport, globalBaseUrlKey, errorLabel, }?: LazyRuntimeLoaderOptions): Promise<unknown>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type JwtProvider } from './jwt-mint.js';
|
|
2
|
+
interface InvokeBeOpArgs {
|
|
3
|
+
beUrl: string;
|
|
4
|
+
accountId: string;
|
|
5
|
+
devJwtSecret?: string | undefined;
|
|
6
|
+
tokenBrokerUrl?: string | undefined;
|
|
7
|
+
tokenBrokerAudience?: string | undefined;
|
|
8
|
+
jwtProvider?: JwtProvider | undefined;
|
|
9
|
+
parentUrl?: string | undefined;
|
|
10
|
+
op: string;
|
|
11
|
+
input?: unknown;
|
|
12
|
+
signal?: AbortSignal | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function invokeBeOp({ beUrl, accountId, devJwtSecret, tokenBrokerUrl, tokenBrokerAudience, jwtProvider, parentUrl, op, input, signal, }: InvokeBeOpArgs): Promise<Record<string, unknown>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ProcessActionRequest } from '../../common/transport.js';
|
|
2
|
+
import type { StreamEvent } from '../../common/types.js';
|
|
3
|
+
import type { AccountModule, BeClient, ChatContext, RpcFn, ToolBridge } from '../types.js';
|
|
4
|
+
interface RunTurnArgs {
|
|
5
|
+
request: ProcessActionRequest;
|
|
6
|
+
accountModule: AccountModule;
|
|
7
|
+
contextStore: {
|
|
8
|
+
load: (request: ProcessActionRequest) => Promise<ChatContext>;
|
|
9
|
+
patch: (threadId: string, patch: Partial<ChatContext> | null | undefined) => ChatContext | null;
|
|
10
|
+
appendUserMessage: (threadId: string, text: string) => ChatContext | null;
|
|
11
|
+
commit: (threadId: string) => Promise<ChatContext | null>;
|
|
12
|
+
};
|
|
13
|
+
beClient: BeClient;
|
|
14
|
+
toolBridge: ToolBridge;
|
|
15
|
+
emit: (event: StreamEvent) => void;
|
|
16
|
+
rpc: RpcFn;
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
interface RunTurnResult {
|
|
20
|
+
steps: number;
|
|
21
|
+
productSkusEmitted: string[];
|
|
22
|
+
}
|
|
23
|
+
export declare function runTurn({ request, accountModule, contextStore, beClient, toolBridge, emit, rpc, signal, }: RunTurnArgs): Promise<RunTurnResult>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
interface MintDevJwtArgs {
|
|
2
|
+
accountId: string;
|
|
3
|
+
devJwtSecret?: string;
|
|
4
|
+
ttlS?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function mintDevJwt({ accountId, devJwtSecret, ttlS }: MintDevJwtArgs): Promise<string>;
|
|
7
|
+
interface JwtProviderOptions {
|
|
8
|
+
accountId: string;
|
|
9
|
+
devJwtSecret?: string | undefined;
|
|
10
|
+
tokenBrokerUrl?: string | undefined;
|
|
11
|
+
tokenBrokerAudience?: string | undefined;
|
|
12
|
+
refreshSkewS?: number | undefined;
|
|
13
|
+
fetchImpl?: typeof fetch | undefined;
|
|
14
|
+
}
|
|
15
|
+
interface JwtProviderArgs {
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
parentUrl?: string;
|
|
18
|
+
}
|
|
19
|
+
export type JwtProvider = (args?: JwtProviderArgs) => Promise<string>;
|
|
20
|
+
export declare function createJwtProvider({ accountId, devJwtSecret, tokenBrokerUrl, tokenBrokerAudience, refreshSkewS, fetchImpl, }: JwtProviderOptions): JwtProvider;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentBeaconPayload, RpcFn, ToolMap } from '../types.js';
|
|
2
|
+
interface MemoryLike {
|
|
3
|
+
getItem: (key: string) => string | null;
|
|
4
|
+
setItem: (key: string, value: string) => void;
|
|
5
|
+
}
|
|
6
|
+
interface MainRpcDeps {
|
|
7
|
+
tools: ToolMap;
|
|
8
|
+
beacon?: ((payload: AgentBeaconPayload) => void) | undefined;
|
|
9
|
+
memory: MemoryLike;
|
|
10
|
+
}
|
|
11
|
+
interface RpcScope {
|
|
12
|
+
addEventListener: (type: 'message', listener: (event: MessageEvent) => void) => void;
|
|
13
|
+
postMessage: (message: unknown, transfer?: Transferable[]) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function createWorkerRpc(scope?: RpcScope): RpcFn;
|
|
16
|
+
interface HandleMainRpcArgs {
|
|
17
|
+
worker: Worker;
|
|
18
|
+
tools?: ToolMap;
|
|
19
|
+
beacon?: (payload: AgentBeaconPayload) => void;
|
|
20
|
+
memory?: MemoryLike;
|
|
21
|
+
}
|
|
22
|
+
export declare function handleMainRpc({ worker, tools, beacon, memory }: HandleMainRpcArgs): void;
|
|
23
|
+
export declare function runMainRpc(method: string, payload: unknown, { tools, beacon, memory }: MainRpcDeps): Promise<unknown>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { ContextStore } from './context/context-store.js';
|
|
2
|
+
export { action, done, error, metadata, textChunk, uiSpec } from './events/builders.js';
|
|
3
|
+
export { AgentError, beErrorToAgentError, caughtToStreamError, httpErrorToAgentError, } from './events/error-taxonomy.js';
|
|
4
|
+
export { normalizeProduct, trimProductFactsCore, trimProductFactsListCore } from './events/product-normalize.js';
|
|
5
|
+
export { actionButtonsUiSpec, comparisonUiSpec, productDetailsUiSpec, productsUiSpec } from './events/ui-specs.js';
|
|
6
|
+
export { beautyConsultingTurnFlow } from './flow/beauty-consulting-turn.js';
|
|
7
|
+
export { createFlow } from './flow/create-flow.js';
|
|
8
|
+
export { resolveFlow } from './flow/dispatch.js';
|
|
9
|
+
export { requestText } from './util/request-text.js';
|
|
10
|
+
export { elapsedMs, nowIso } from './util/time.js';
|
|
11
|
+
export { invokeBeOp } from './worker/be-client.js';
|
|
12
|
+
export { startWorker } from './worker/entry.js';
|
|
13
|
+
export { runTurn } from './worker/flow-runner.js';
|
|
14
|
+
export { createJwtProvider, mintDevJwt } from './worker/jwt-mint.js';
|
|
15
|
+
export { createWorkerRpc, handleMainRpc, runMainRpc } from './worker/rpc.js';
|
|
16
|
+
export { createToolBridge } from './worker/tool-bridge.js';
|
|
@@ -0,0 +1,119 @@
|
|
|
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);
|
|
4
|
+
let e = null, u = null, l = null, p = "";
|
|
5
|
+
n.addEventListener("message", (t) => {
|
|
6
|
+
const r = t.data;
|
|
7
|
+
if (r) {
|
|
8
|
+
if (r.type === "abort") {
|
|
9
|
+
typeof r.id == "number" && (a.get(r.id)?.abort(), a.delete(r.id));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
r.type === "invoke" && w(r);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
async function w(t) {
|
|
16
|
+
e = {
|
|
17
|
+
accountId: String(t.accountId || c.accountId || ""),
|
|
18
|
+
beUrl: t.beUrl || "",
|
|
19
|
+
...t.devJwtSecret ? { devJwtSecret: t.devJwtSecret } : {},
|
|
20
|
+
...t.tokenBrokerUrl ? { tokenBrokerUrl: t.tokenBrokerUrl } : {},
|
|
21
|
+
...t.tokenBrokerAudience ? { tokenBrokerAudience: t.tokenBrokerAudience } : {},
|
|
22
|
+
locale: t.defaultLocale || c.defaultLocale || "en-GB",
|
|
23
|
+
parentUrl: t.parentUrl || ""
|
|
24
|
+
};
|
|
25
|
+
const r = [
|
|
26
|
+
e.accountId,
|
|
27
|
+
e.devJwtSecret || "",
|
|
28
|
+
e.tokenBrokerUrl || "",
|
|
29
|
+
e.tokenBrokerAudience || ""
|
|
30
|
+
].join(`
|
|
31
|
+
`);
|
|
32
|
+
(!l || p !== r) && (l = I(e), p = r), u ||= new B({
|
|
33
|
+
accountId: e.accountId,
|
|
34
|
+
locale: e.locale,
|
|
35
|
+
parentUrl: e.parentUrl,
|
|
36
|
+
rpc: i
|
|
37
|
+
});
|
|
38
|
+
const d = new AbortController();
|
|
39
|
+
a.set(t.id, d);
|
|
40
|
+
const s = (o) => {
|
|
41
|
+
n.postMessage({
|
|
42
|
+
id: t.id,
|
|
43
|
+
type: "event",
|
|
44
|
+
event: o
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
try {
|
|
48
|
+
const o = e, U = l;
|
|
49
|
+
await P({
|
|
50
|
+
request: t.request || {},
|
|
51
|
+
accountModule: {
|
|
52
|
+
...c,
|
|
53
|
+
accountId: o.accountId
|
|
54
|
+
},
|
|
55
|
+
contextStore: u,
|
|
56
|
+
beClient: { invoke({ op: f, input: b, signal: k }) {
|
|
57
|
+
return A({
|
|
58
|
+
beUrl: o.beUrl,
|
|
59
|
+
accountId: o.accountId,
|
|
60
|
+
jwtProvider: U,
|
|
61
|
+
parentUrl: o.parentUrl,
|
|
62
|
+
op: f,
|
|
63
|
+
input: b,
|
|
64
|
+
...k ? { signal: k } : {}
|
|
65
|
+
});
|
|
66
|
+
} },
|
|
67
|
+
toolBridge: v,
|
|
68
|
+
emit: s,
|
|
69
|
+
rpc: i,
|
|
70
|
+
signal: d.signal
|
|
71
|
+
}), n.postMessage({
|
|
72
|
+
id: t.id,
|
|
73
|
+
type: "end"
|
|
74
|
+
});
|
|
75
|
+
} catch (o) {
|
|
76
|
+
d.signal.aborted || (s(y(o)), s(h()), n.postMessage({
|
|
77
|
+
id: t.id,
|
|
78
|
+
type: "end"
|
|
79
|
+
}));
|
|
80
|
+
} finally {
|
|
81
|
+
a.delete(t.id);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
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,
|
|
95
|
+
I as createJwtProvider,
|
|
96
|
+
C as createToolBridge,
|
|
97
|
+
S as createWorkerRpc,
|
|
98
|
+
h as done,
|
|
99
|
+
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
|
|
119
|
+
};
|
|
@@ -0,0 +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 Ce(e){if(e&&typeof e=="object"&&typeof e.name=="string")return e;throw new Error("tool.invoke requires { name, input }")}function Pe(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 z(e,t,{tools:n,beacon:r,memory:o}){if(e==="tool.invoke"){const{name:a,input:i}=Ce(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}=Pe(t),i=o.getItem(String(a));return i?JSON.parse(i):null}if(e==="memory.set"){const{key:a,value:i}=je(t);return o.setItem(String(a),JSON.stringify(i??null)),{ok:!0}}throw new Error(`Unknown RPC method: ${e}`)}function V(){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=W(i.messages),u={id:String(o||s.id||self.crypto.randomUUID()),started_at:String(s.started_at||V()),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 Ie(e,t){const n=W([t])[0];return n?{...e,messages:[...e.messages,n].slice(-50)}:e}function W(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 Re="gengage:agent:context:";async function Ue({accountId:e,threadId:t,rpc:n}){const r=await n("memory.get",{tier:"session",key:K(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:K(e,t),value:{thread:{extensions:n}}})}function K(e,t){return`${Re}${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=Ie(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 I(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 I({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 I(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 R(){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(R()),{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 Ve(r,t,n),t.context=n.contextStore.patch(t.threadId,{})||t.context}}async function Ve(e,t,n){const r=O(t);if(e.kind==="be_op"){await We(e,t,n,r);return}if(e.kind==="tool"){await Ke(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 We(e,t,n,r){const o=performance.now();let a;try{a=await n.beClient.invoke({op:e.op,input:C(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 Ke(e,t,n,r){const o=await n.toolBridge.invoke(e.name,C(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(C(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(C(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(R()))}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 C(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,Lt)=>d({type:"ui_spec",spec:y,widget:T,...S?{panelHint:S}:{},...Lt?{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.");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 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||{});
|