@burdenoff/website-sdk 2026.1028.1 → 2026.1029.1
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 +159 -1
- package/dist/avatar-live/index.d.mts +11 -0
- package/dist/avatar-live/index.d.ts +11 -0
- package/dist/avatar-live/index.js +120 -0
- package/dist/avatar-live/index.js.map +1 -0
- package/dist/avatar-live/index.mjs +118 -0
- package/dist/avatar-live/index.mjs.map +1 -0
- package/dist/avatar-live-view/index.d.mts +42 -0
- package/dist/avatar-live-view/index.d.ts +42 -0
- package/dist/avatar-live-view/index.js +1422 -0
- package/dist/avatar-live-view/index.js.map +1 -0
- package/dist/avatar-live-view/index.mjs +1420 -0
- package/dist/avatar-live-view/index.mjs.map +1 -0
- package/dist/components/explore.d.mts +2 -2
- package/dist/components/explore.d.ts +2 -2
- package/dist/components/explore.js +11 -4
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +11 -4
- package/dist/components/explore.mjs.map +1 -1
- package/dist/{explore-BEgq1_0O.d.mts → explore-DUTNYUOm.d.mts} +1 -1
- package/dist/{explore-CHiP9u-4.d.ts → explore-DjQE7Xia.d.ts} +1 -1
- package/dist/explore-avatar-live-config-B171o1Yo.d.ts +283 -0
- package/dist/explore-avatar-live-config-BGsGwbcq.d.mts +283 -0
- package/dist/{explore-types-_9UJu6EA.d.mts → explore-types-Bb2Ih3d8.d.mts} +1 -1
- package/dist/{explore-types-_9UJu6EA.d.ts → explore-types-Bb2Ih3d8.d.ts} +1 -1
- package/dist/hooks/index.d.mts +3 -2
- package/dist/hooks/index.d.ts +3 -2
- package/dist/hooks/index.js +6 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +6 -1
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +16 -253
- package/dist/index.d.ts +16 -253
- package/dist/index.js +214 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +214 -36
- package/dist/index.mjs.map +1 -1
- package/dist/types-CndbmBK-.d.mts +68 -0
- package/dist/types-CndbmBK-.d.ts +68 -0
- package/dist/{use-progressive-reveal-C0hkdu_i.d.ts → use-explore-chat-DunjG-3p.d.ts} +10 -36
- package/dist/{use-progressive-reveal-BFPWbEXy.d.mts → use-explore-chat-zRuoAin6.d.mts} +10 -36
- package/dist/use-progressive-reveal-ppicEgzZ.d.mts +35 -0
- package/dist/use-progressive-reveal-ppicEgzZ.d.ts +35 -0
- package/package.json +15 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { e as ExploreProduct, f as ExploreReference } from './explore-types-Bb2Ih3d8.mjs';
|
|
3
3
|
import { Components } from 'react-markdown';
|
|
4
4
|
|
|
5
5
|
/** The words the player needs. `AnswerRendererStrings`, and so `ExploreStrings`, carry them. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { e as ExploreProduct, f as ExploreReference } from './explore-types-Bb2Ih3d8.js';
|
|
3
3
|
import { Components } from 'react-markdown';
|
|
4
4
|
|
|
5
5
|
/** The words the player needs. `AnswerRendererStrings`, and so `ExploreStrings`, carry them. */
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { A as AvatarLiveModule } from './types-CndbmBK-.js';
|
|
2
|
+
import { e as UseExploreChatResult } from './use-explore-chat-DunjG-3p.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Localisation for the `/explore` chat surface.
|
|
6
|
+
*
|
|
7
|
+
* ## Why this is self-contained
|
|
8
|
+
*
|
|
9
|
+
* The app shells localise through `useI18n()` from `@burdenoff/fe-libs`, which is mounted by
|
|
10
|
+
* `AppShellProvider` and fetches translations at runtime from `global-i18n-svc`. None of that
|
|
11
|
+
* exists on a marketing website: no provider, no dictionary, no locale routing, and no
|
|
12
|
+
* translation files in any of the 39 site repos. Pulling that machinery in would mean adding
|
|
13
|
+
* a runtime translation fetch to a static prerendered page — a network round-trip in front of
|
|
14
|
+
* the first paint, on pages whose whole point is that they are prerendered.
|
|
15
|
+
*
|
|
16
|
+
* So the strings are bundled. There are few enough of them that the cost is bytes rather than
|
|
17
|
+
* a request, and a prerendered page stays fully rendered.
|
|
18
|
+
*
|
|
19
|
+
* ## Locales
|
|
20
|
+
*
|
|
21
|
+
* The six the products actually ship, taken from `{product}-app/src/components/chrome/
|
|
22
|
+
* languages.ts` (FALLBACK_LANGUAGES). Deliberately NOT the wider `Locale` union in fe-libs,
|
|
23
|
+
* which also lists fr/de/ja that no product ships, and deliberately not the backend's BCP-47
|
|
24
|
+
* set, which has fr/de/ja but lacks ta and ar.
|
|
25
|
+
*/
|
|
26
|
+
declare const EXPLORE_LOCALES: readonly ["en", "zh", "hi", "es", "ar", "ta"];
|
|
27
|
+
type ExploreLocale = (typeof EXPLORE_LOCALES)[number];
|
|
28
|
+
interface ExploreStrings {
|
|
29
|
+
badge: string;
|
|
30
|
+
welcomeTitle: string;
|
|
31
|
+
welcomeBody: string;
|
|
32
|
+
/**
|
|
33
|
+
* BOFF-9796: the welcome body of ONE product's own assistant (`scope="product"`) when the host passes none. Takes
|
|
34
|
+
* `{product}`. Problem-first like `welcomeBody`, and unlike the catalog's copy for a product site it offers nothing
|
|
35
|
+
* beyond that product: no "compare it with anything else we build".
|
|
36
|
+
*/
|
|
37
|
+
welcomeBodyProduct: string;
|
|
38
|
+
/**
|
|
39
|
+
* BOFF-9796: the product scope's welcome body when no product name is known (a slug no catalog lists, and no
|
|
40
|
+
* `productName`). Like `welcomeBodyProduct` without the name, so it never falls back to the portfolio's invitation
|
|
41
|
+
* to "ask about a specific product or compare a few".
|
|
42
|
+
*/
|
|
43
|
+
welcomeBodyScoped: string;
|
|
44
|
+
tryAsking: string;
|
|
45
|
+
focusProduct: string;
|
|
46
|
+
allProducts: string;
|
|
47
|
+
showAll: string;
|
|
48
|
+
showLess: string;
|
|
49
|
+
sources: string;
|
|
50
|
+
nextYouCouldAsk: string;
|
|
51
|
+
placeholder: string;
|
|
52
|
+
placeholderProduct: string;
|
|
53
|
+
/**
|
|
54
|
+
* BOFF-9796: the composer's placeholder on ONE product's own assistant (`scope="product"`). Takes `{product}`.
|
|
55
|
+
* Short on purpose, and the one thing about the composer that the product scope changes: the field is the published
|
|
56
|
+
* one, one line tall on a phone, where a placeholder that wraps loses its second line. `placeholderProduct`
|
|
57
|
+
* ("Describe a problem, or ask about Healthy Bowl…") wraps there at 390px and under; the English "Ask about Healthy
|
|
58
|
+
* Bowl…" fits one line at 320px and wider. Spanish and Tamil, the longest here, may still wrap at 320px and
|
|
59
|
+
* narrower: a follow-up (HealthyBowl, the site this was made for, is English-only). The welcome above the composer
|
|
60
|
+
* already asks for the problem.
|
|
61
|
+
*/
|
|
62
|
+
placeholderScoped: string;
|
|
63
|
+
send: string;
|
|
64
|
+
stop: string;
|
|
65
|
+
newChat: string;
|
|
66
|
+
history: string;
|
|
67
|
+
clearHistory: string;
|
|
68
|
+
share: string;
|
|
69
|
+
copied: string;
|
|
70
|
+
copying: string;
|
|
71
|
+
shareUnavailable: string;
|
|
72
|
+
disclaimer: string;
|
|
73
|
+
disclaimerShort: string;
|
|
74
|
+
dictate: string;
|
|
75
|
+
stopDictating: string;
|
|
76
|
+
attach: string;
|
|
77
|
+
attachHint: string;
|
|
78
|
+
removeAttachment: string;
|
|
79
|
+
attachmentNameOnly: string;
|
|
80
|
+
attachmentTooLarge: string;
|
|
81
|
+
attachmentTooMany: string;
|
|
82
|
+
noAnswer: string;
|
|
83
|
+
answerDidNotArrive: string;
|
|
84
|
+
/**
|
|
85
|
+
* BOFF-9796: what a turn that ran out of searches (`TOOL_BUDGET`) says on ONE product's own assistant
|
|
86
|
+
* (`scope="product"`). The default message asks for "two or three specific products", an invitation to other
|
|
87
|
+
* products that a product's own assistant must not make; here the narrowing offered is to one part of the question.
|
|
88
|
+
*/
|
|
89
|
+
toolBudgetScoped: string;
|
|
90
|
+
askHuman: string;
|
|
91
|
+
feedbackPrompt: string;
|
|
92
|
+
feedbackHelpful: string;
|
|
93
|
+
feedbackNotHelpful: string;
|
|
94
|
+
feedbackReasonTitle: string;
|
|
95
|
+
feedbackReasonInaccurate: string;
|
|
96
|
+
feedbackReasonIncomplete: string;
|
|
97
|
+
feedbackReasonOffTopic: string;
|
|
98
|
+
feedbackReasonHardToFollow: string;
|
|
99
|
+
feedbackReasonOther: string;
|
|
100
|
+
feedbackCommentPlaceholder: string;
|
|
101
|
+
feedbackSend: string;
|
|
102
|
+
feedbackDismiss: string;
|
|
103
|
+
feedbackThanks: string;
|
|
104
|
+
feedbackNotSent: string;
|
|
105
|
+
/**
|
|
106
|
+
* The trigger, in its two homes: `escalateOpen` is the quiet one under an answer we DID
|
|
107
|
+
* give, and the amber "we could not find this" banner reuses `askHuman` so that sentence
|
|
108
|
+
* keeps reading as one sentence.
|
|
109
|
+
*/
|
|
110
|
+
escalateOpen: string;
|
|
111
|
+
escalateTitle: string;
|
|
112
|
+
escalateBody: string;
|
|
113
|
+
escalateEmailLabel: string;
|
|
114
|
+
escalateEmailPlaceholder: string;
|
|
115
|
+
escalateNoteLabel: string;
|
|
116
|
+
escalateSubmit: string;
|
|
117
|
+
escalateSending: string;
|
|
118
|
+
escalateCancel: string;
|
|
119
|
+
/**
|
|
120
|
+
* Shown for BOTH the client's own pre-flight and the server's `INVALID_EMAIL`. The two
|
|
121
|
+
* disagree about what is deliverable and the server is right, but the visitor's next
|
|
122
|
+
* action is identical either way: check the address.
|
|
123
|
+
*/
|
|
124
|
+
escalateInvalidEmail: string;
|
|
125
|
+
/**
|
|
126
|
+
* The success line. Takes `{email}` — and it is filled with the address the SERVER
|
|
127
|
+
* returned, not the one in the box, because on a repeat handover the reply goes to
|
|
128
|
+
* whichever address the first one used.
|
|
129
|
+
*
|
|
130
|
+
* Used for `created: false` as well: a visitor asking for help is not told "you already
|
|
131
|
+
* did that".
|
|
132
|
+
*/
|
|
133
|
+
escalateSent: string;
|
|
134
|
+
escalateRateLimited: string;
|
|
135
|
+
escalateCaptcha: string;
|
|
136
|
+
escalateFailed: string;
|
|
137
|
+
prevSuggestion: string;
|
|
138
|
+
nextSuggestion: string;
|
|
139
|
+
/**
|
|
140
|
+
* The label every concept picture carries, wherever one is shown — inside an answer and on
|
|
141
|
+
* the welcome strip alike.
|
|
142
|
+
*
|
|
143
|
+
* These images are published mockups, so the page has to say so; it says it in ONE wording,
|
|
144
|
+
* because two phrasings for the same caveat read as two different caveats.
|
|
145
|
+
*/
|
|
146
|
+
conceptIllustration: string;
|
|
147
|
+
/** Rail arrows on the concept strip — pointer devices only. */
|
|
148
|
+
conceptScrollPrev: string;
|
|
149
|
+
conceptScrollNext: string;
|
|
150
|
+
opensInNewTab: string;
|
|
151
|
+
/** Heading over the concept strip on the welcome screen. */
|
|
152
|
+
conceptStripTitle: string;
|
|
153
|
+
/** Accessible name of the strip itself. */
|
|
154
|
+
conceptStripLabel: string;
|
|
155
|
+
/** Accessible name of one card. Takes `{title}` and `{product}`. */
|
|
156
|
+
conceptAsk: string;
|
|
157
|
+
/**
|
|
158
|
+
* The question a card actually SENDS. Takes `{title}` and `{product}`.
|
|
159
|
+
*
|
|
160
|
+
* Localised because it becomes the visitor's own message in the transcript — an English
|
|
161
|
+
* sentence appearing above an Arabic answer would read as the page talking to itself.
|
|
162
|
+
*/
|
|
163
|
+
conceptAskQuestion: string;
|
|
164
|
+
/** Label of the per-answer copy control, and its failure state. */
|
|
165
|
+
copyAnswer: string;
|
|
166
|
+
copyFailed: string;
|
|
167
|
+
/**
|
|
168
|
+
* Label of the per-answer read-aloud control, in its two states.
|
|
169
|
+
*
|
|
170
|
+
* A toggle, exactly like the composer's dictation button: one control whose label says
|
|
171
|
+
* what pressing it does NOW, never a second button that appears while it is speaking.
|
|
172
|
+
*/
|
|
173
|
+
readAloud: string;
|
|
174
|
+
stopReading: string;
|
|
175
|
+
/**
|
|
176
|
+
* Accessible name of the scrollable box a table in an answer sits in.
|
|
177
|
+
*
|
|
178
|
+
* A scrollable region needs a name and a tab stop, or a keyboard visitor cannot reach the
|
|
179
|
+
* columns that are off the edge. The `<table>` inside it keeps its own semantics.
|
|
180
|
+
*/
|
|
181
|
+
answerTable: string;
|
|
182
|
+
/**
|
|
183
|
+
* The product-video card in an answer (CONTRACT.md §7) and the player it opens.
|
|
184
|
+
*
|
|
185
|
+
* `productVideo` is the card's badge — the video counterpart of `conceptIllustration` —
|
|
186
|
+
* and names a video the answer gave no title. `productVideoTitle` names the video in this
|
|
187
|
+
* language and takes `{product}`: the harness always writes the line's text as the English
|
|
188
|
+
* "<Name> product video", so the card keeps only the name from it. `playVideo` is the
|
|
189
|
+
* card's accessible name and takes `{title}`, which is that name. The last four belong to
|
|
190
|
+
* the player: its Close button, the two states of its full-screen toggle, and the line
|
|
191
|
+
* shown in place of a video that cannot be played.
|
|
192
|
+
*/
|
|
193
|
+
productVideo: string;
|
|
194
|
+
productVideoTitle: string;
|
|
195
|
+
playVideo: string;
|
|
196
|
+
closeVideo: string;
|
|
197
|
+
enterFullScreen: string;
|
|
198
|
+
exitFullScreen: string;
|
|
199
|
+
/**
|
|
200
|
+
* BOFF-9697: the site-wide assistant panel (`ExplorePanel`). The tab, view and avatar words are the ones the product
|
|
201
|
+
* apps' assistant already ships in all six locales (Chat, Avatar, Live avatar, Assistant views).
|
|
202
|
+
*/
|
|
203
|
+
panelTitle: string;
|
|
204
|
+
/**
|
|
205
|
+
* BOFF-9796: the panel's title on one product's own assistant (`scope="product"`), "{product} assistant" in each
|
|
206
|
+
* language's own word order. Takes `{product}`. `panelTitle` stays the title wherever no product name is known.
|
|
207
|
+
*/
|
|
208
|
+
panelTitleProduct: string;
|
|
209
|
+
panelViews: string;
|
|
210
|
+
tabChat: string;
|
|
211
|
+
tabAvatar: string;
|
|
212
|
+
closePanel: string;
|
|
213
|
+
liveAvatar: string;
|
|
214
|
+
avatarComingSoon: string;
|
|
215
|
+
continueInChat: string;
|
|
216
|
+
videoUnavailable: string;
|
|
217
|
+
/** Accessible name of the provenance row under an answer. */
|
|
218
|
+
groundedIn: string;
|
|
219
|
+
/** How many sources the answer cites. `sourceCountMany` takes `{count}`. */
|
|
220
|
+
sourceCountOne: string;
|
|
221
|
+
sourceCountMany: string;
|
|
222
|
+
/** What KIND of page a source is, inferred from its URL. */
|
|
223
|
+
sourceKindConcept: string;
|
|
224
|
+
sourceKindDocs: string;
|
|
225
|
+
sourceKindPricing: string;
|
|
226
|
+
sourceKindUseCase: string;
|
|
227
|
+
sourceKindPage: string;
|
|
228
|
+
/**
|
|
229
|
+
* The page's <title> and <meta description>.
|
|
230
|
+
*
|
|
231
|
+
* These are the surface a search result and a browser tab are built from, and they are
|
|
232
|
+
* the LAST place the old product-first framing survived: all 38 sites hard-coded
|
|
233
|
+
* "Explore Burdenoff products with AI" inline, so the tab announced our catalogue on a
|
|
234
|
+
* page that asks the visitor about their problem — and named the wrong brand on 37 of
|
|
235
|
+
* them. `seoTitle` carries no brand: PageHead appends "| {productName}" itself.
|
|
236
|
+
*/
|
|
237
|
+
seoTitle: string;
|
|
238
|
+
seoDescription: string;
|
|
239
|
+
/** Used when the page belongs to a specific product's site. Takes `{product}`. */
|
|
240
|
+
seoDescriptionProduct: string;
|
|
241
|
+
/**
|
|
242
|
+
* BOFF-9796: the meta description of ONE product's own `/explore` (`scope="product"`). Takes `{product}`. Unlike
|
|
243
|
+
* `seoDescriptionProduct`, it promises nothing beyond that product: no "and every other product we build".
|
|
244
|
+
*/
|
|
245
|
+
seoDescriptionScoped: string;
|
|
246
|
+
capabilities: [string, string, string];
|
|
247
|
+
prompts: string[];
|
|
248
|
+
}
|
|
249
|
+
declare function speechLocaleOf(locale: ExploreLocale): string;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* BOFF-9797. The small part of the live avatar that the panel itself needs, whether or not it is ever opened: what a
|
|
253
|
+
* host's `avatar.live` is, whether the live avatar can run on this page at all, and where its requests go.
|
|
254
|
+
*
|
|
255
|
+
* Everything else (the view, its state machine, the requests, the words, the bot check) is a separate chunk that a
|
|
256
|
+
* site only downloads when its visitor first opens the Avatar view (see `explore-avatar-live.tsx`). That is why this
|
|
257
|
+
* file is separate and kept to a few lines: it is the only part of the live avatar in the package root for a site that
|
|
258
|
+
* does not pass `avatar.live`, and the part of it that decides, without loading anything, whether the chunk is wanted.
|
|
259
|
+
* Types only, plus plain functions: nothing here imports a component, a context or a string table.
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* BOFF-9797. A host's opt-in to the live avatar on its panel's Avatar tab. Every field is required; a config that is
|
|
264
|
+
* incomplete leaves the tab as it was (and a warning in the console).
|
|
265
|
+
*/
|
|
266
|
+
interface ExplorePanelAvatarLive {
|
|
267
|
+
/** The site, as the live avatar service knows it: `healthybowl`. */
|
|
268
|
+
site: string;
|
|
269
|
+
/**
|
|
270
|
+
* Loads the live avatar's room module: `() => import('@burdenoff/website-sdk/avatar-live')`. Called only after the
|
|
271
|
+
* visitor presses Start on the consent card, never on page load or on opening the tab. That entry needs the
|
|
272
|
+
* package's optional peer dependency for media rooms (see the README).
|
|
273
|
+
*/
|
|
274
|
+
load: () => Promise<AvatarLiveModule>;
|
|
275
|
+
/** The site's Cloudflare Turnstile site key, for the bot check that runs when the visitor presses Start. */
|
|
276
|
+
turnstileSiteKey: string;
|
|
277
|
+
/** The version of the suggested-question list the panel shows (its `examplePrompts`), such as `hb-en-1`. */
|
|
278
|
+
manifestVersion: string;
|
|
279
|
+
}
|
|
280
|
+
/** What the live avatar reads of the panel's conversation: the transcript, whether it is read-only, and the token. */
|
|
281
|
+
type AvatarConversation = Pick<UseExploreChatResult, "messages" | "isSharedView" | "getConversationToken">;
|
|
282
|
+
|
|
283
|
+
export { type AvatarConversation as A, type ExplorePanelAvatarLive as E, type ExploreLocale as a, EXPLORE_LOCALES as b, type ExploreStrings as c, speechLocaleOf as s };
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { A as AvatarLiveModule } from './types-CndbmBK-.mjs';
|
|
2
|
+
import { e as UseExploreChatResult } from './use-explore-chat-zRuoAin6.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Localisation for the `/explore` chat surface.
|
|
6
|
+
*
|
|
7
|
+
* ## Why this is self-contained
|
|
8
|
+
*
|
|
9
|
+
* The app shells localise through `useI18n()` from `@burdenoff/fe-libs`, which is mounted by
|
|
10
|
+
* `AppShellProvider` and fetches translations at runtime from `global-i18n-svc`. None of that
|
|
11
|
+
* exists on a marketing website: no provider, no dictionary, no locale routing, and no
|
|
12
|
+
* translation files in any of the 39 site repos. Pulling that machinery in would mean adding
|
|
13
|
+
* a runtime translation fetch to a static prerendered page — a network round-trip in front of
|
|
14
|
+
* the first paint, on pages whose whole point is that they are prerendered.
|
|
15
|
+
*
|
|
16
|
+
* So the strings are bundled. There are few enough of them that the cost is bytes rather than
|
|
17
|
+
* a request, and a prerendered page stays fully rendered.
|
|
18
|
+
*
|
|
19
|
+
* ## Locales
|
|
20
|
+
*
|
|
21
|
+
* The six the products actually ship, taken from `{product}-app/src/components/chrome/
|
|
22
|
+
* languages.ts` (FALLBACK_LANGUAGES). Deliberately NOT the wider `Locale` union in fe-libs,
|
|
23
|
+
* which also lists fr/de/ja that no product ships, and deliberately not the backend's BCP-47
|
|
24
|
+
* set, which has fr/de/ja but lacks ta and ar.
|
|
25
|
+
*/
|
|
26
|
+
declare const EXPLORE_LOCALES: readonly ["en", "zh", "hi", "es", "ar", "ta"];
|
|
27
|
+
type ExploreLocale = (typeof EXPLORE_LOCALES)[number];
|
|
28
|
+
interface ExploreStrings {
|
|
29
|
+
badge: string;
|
|
30
|
+
welcomeTitle: string;
|
|
31
|
+
welcomeBody: string;
|
|
32
|
+
/**
|
|
33
|
+
* BOFF-9796: the welcome body of ONE product's own assistant (`scope="product"`) when the host passes none. Takes
|
|
34
|
+
* `{product}`. Problem-first like `welcomeBody`, and unlike the catalog's copy for a product site it offers nothing
|
|
35
|
+
* beyond that product: no "compare it with anything else we build".
|
|
36
|
+
*/
|
|
37
|
+
welcomeBodyProduct: string;
|
|
38
|
+
/**
|
|
39
|
+
* BOFF-9796: the product scope's welcome body when no product name is known (a slug no catalog lists, and no
|
|
40
|
+
* `productName`). Like `welcomeBodyProduct` without the name, so it never falls back to the portfolio's invitation
|
|
41
|
+
* to "ask about a specific product or compare a few".
|
|
42
|
+
*/
|
|
43
|
+
welcomeBodyScoped: string;
|
|
44
|
+
tryAsking: string;
|
|
45
|
+
focusProduct: string;
|
|
46
|
+
allProducts: string;
|
|
47
|
+
showAll: string;
|
|
48
|
+
showLess: string;
|
|
49
|
+
sources: string;
|
|
50
|
+
nextYouCouldAsk: string;
|
|
51
|
+
placeholder: string;
|
|
52
|
+
placeholderProduct: string;
|
|
53
|
+
/**
|
|
54
|
+
* BOFF-9796: the composer's placeholder on ONE product's own assistant (`scope="product"`). Takes `{product}`.
|
|
55
|
+
* Short on purpose, and the one thing about the composer that the product scope changes: the field is the published
|
|
56
|
+
* one, one line tall on a phone, where a placeholder that wraps loses its second line. `placeholderProduct`
|
|
57
|
+
* ("Describe a problem, or ask about Healthy Bowl…") wraps there at 390px and under; the English "Ask about Healthy
|
|
58
|
+
* Bowl…" fits one line at 320px and wider. Spanish and Tamil, the longest here, may still wrap at 320px and
|
|
59
|
+
* narrower: a follow-up (HealthyBowl, the site this was made for, is English-only). The welcome above the composer
|
|
60
|
+
* already asks for the problem.
|
|
61
|
+
*/
|
|
62
|
+
placeholderScoped: string;
|
|
63
|
+
send: string;
|
|
64
|
+
stop: string;
|
|
65
|
+
newChat: string;
|
|
66
|
+
history: string;
|
|
67
|
+
clearHistory: string;
|
|
68
|
+
share: string;
|
|
69
|
+
copied: string;
|
|
70
|
+
copying: string;
|
|
71
|
+
shareUnavailable: string;
|
|
72
|
+
disclaimer: string;
|
|
73
|
+
disclaimerShort: string;
|
|
74
|
+
dictate: string;
|
|
75
|
+
stopDictating: string;
|
|
76
|
+
attach: string;
|
|
77
|
+
attachHint: string;
|
|
78
|
+
removeAttachment: string;
|
|
79
|
+
attachmentNameOnly: string;
|
|
80
|
+
attachmentTooLarge: string;
|
|
81
|
+
attachmentTooMany: string;
|
|
82
|
+
noAnswer: string;
|
|
83
|
+
answerDidNotArrive: string;
|
|
84
|
+
/**
|
|
85
|
+
* BOFF-9796: what a turn that ran out of searches (`TOOL_BUDGET`) says on ONE product's own assistant
|
|
86
|
+
* (`scope="product"`). The default message asks for "two or three specific products", an invitation to other
|
|
87
|
+
* products that a product's own assistant must not make; here the narrowing offered is to one part of the question.
|
|
88
|
+
*/
|
|
89
|
+
toolBudgetScoped: string;
|
|
90
|
+
askHuman: string;
|
|
91
|
+
feedbackPrompt: string;
|
|
92
|
+
feedbackHelpful: string;
|
|
93
|
+
feedbackNotHelpful: string;
|
|
94
|
+
feedbackReasonTitle: string;
|
|
95
|
+
feedbackReasonInaccurate: string;
|
|
96
|
+
feedbackReasonIncomplete: string;
|
|
97
|
+
feedbackReasonOffTopic: string;
|
|
98
|
+
feedbackReasonHardToFollow: string;
|
|
99
|
+
feedbackReasonOther: string;
|
|
100
|
+
feedbackCommentPlaceholder: string;
|
|
101
|
+
feedbackSend: string;
|
|
102
|
+
feedbackDismiss: string;
|
|
103
|
+
feedbackThanks: string;
|
|
104
|
+
feedbackNotSent: string;
|
|
105
|
+
/**
|
|
106
|
+
* The trigger, in its two homes: `escalateOpen` is the quiet one under an answer we DID
|
|
107
|
+
* give, and the amber "we could not find this" banner reuses `askHuman` so that sentence
|
|
108
|
+
* keeps reading as one sentence.
|
|
109
|
+
*/
|
|
110
|
+
escalateOpen: string;
|
|
111
|
+
escalateTitle: string;
|
|
112
|
+
escalateBody: string;
|
|
113
|
+
escalateEmailLabel: string;
|
|
114
|
+
escalateEmailPlaceholder: string;
|
|
115
|
+
escalateNoteLabel: string;
|
|
116
|
+
escalateSubmit: string;
|
|
117
|
+
escalateSending: string;
|
|
118
|
+
escalateCancel: string;
|
|
119
|
+
/**
|
|
120
|
+
* Shown for BOTH the client's own pre-flight and the server's `INVALID_EMAIL`. The two
|
|
121
|
+
* disagree about what is deliverable and the server is right, but the visitor's next
|
|
122
|
+
* action is identical either way: check the address.
|
|
123
|
+
*/
|
|
124
|
+
escalateInvalidEmail: string;
|
|
125
|
+
/**
|
|
126
|
+
* The success line. Takes `{email}` — and it is filled with the address the SERVER
|
|
127
|
+
* returned, not the one in the box, because on a repeat handover the reply goes to
|
|
128
|
+
* whichever address the first one used.
|
|
129
|
+
*
|
|
130
|
+
* Used for `created: false` as well: a visitor asking for help is not told "you already
|
|
131
|
+
* did that".
|
|
132
|
+
*/
|
|
133
|
+
escalateSent: string;
|
|
134
|
+
escalateRateLimited: string;
|
|
135
|
+
escalateCaptcha: string;
|
|
136
|
+
escalateFailed: string;
|
|
137
|
+
prevSuggestion: string;
|
|
138
|
+
nextSuggestion: string;
|
|
139
|
+
/**
|
|
140
|
+
* The label every concept picture carries, wherever one is shown — inside an answer and on
|
|
141
|
+
* the welcome strip alike.
|
|
142
|
+
*
|
|
143
|
+
* These images are published mockups, so the page has to say so; it says it in ONE wording,
|
|
144
|
+
* because two phrasings for the same caveat read as two different caveats.
|
|
145
|
+
*/
|
|
146
|
+
conceptIllustration: string;
|
|
147
|
+
/** Rail arrows on the concept strip — pointer devices only. */
|
|
148
|
+
conceptScrollPrev: string;
|
|
149
|
+
conceptScrollNext: string;
|
|
150
|
+
opensInNewTab: string;
|
|
151
|
+
/** Heading over the concept strip on the welcome screen. */
|
|
152
|
+
conceptStripTitle: string;
|
|
153
|
+
/** Accessible name of the strip itself. */
|
|
154
|
+
conceptStripLabel: string;
|
|
155
|
+
/** Accessible name of one card. Takes `{title}` and `{product}`. */
|
|
156
|
+
conceptAsk: string;
|
|
157
|
+
/**
|
|
158
|
+
* The question a card actually SENDS. Takes `{title}` and `{product}`.
|
|
159
|
+
*
|
|
160
|
+
* Localised because it becomes the visitor's own message in the transcript — an English
|
|
161
|
+
* sentence appearing above an Arabic answer would read as the page talking to itself.
|
|
162
|
+
*/
|
|
163
|
+
conceptAskQuestion: string;
|
|
164
|
+
/** Label of the per-answer copy control, and its failure state. */
|
|
165
|
+
copyAnswer: string;
|
|
166
|
+
copyFailed: string;
|
|
167
|
+
/**
|
|
168
|
+
* Label of the per-answer read-aloud control, in its two states.
|
|
169
|
+
*
|
|
170
|
+
* A toggle, exactly like the composer's dictation button: one control whose label says
|
|
171
|
+
* what pressing it does NOW, never a second button that appears while it is speaking.
|
|
172
|
+
*/
|
|
173
|
+
readAloud: string;
|
|
174
|
+
stopReading: string;
|
|
175
|
+
/**
|
|
176
|
+
* Accessible name of the scrollable box a table in an answer sits in.
|
|
177
|
+
*
|
|
178
|
+
* A scrollable region needs a name and a tab stop, or a keyboard visitor cannot reach the
|
|
179
|
+
* columns that are off the edge. The `<table>` inside it keeps its own semantics.
|
|
180
|
+
*/
|
|
181
|
+
answerTable: string;
|
|
182
|
+
/**
|
|
183
|
+
* The product-video card in an answer (CONTRACT.md §7) and the player it opens.
|
|
184
|
+
*
|
|
185
|
+
* `productVideo` is the card's badge — the video counterpart of `conceptIllustration` —
|
|
186
|
+
* and names a video the answer gave no title. `productVideoTitle` names the video in this
|
|
187
|
+
* language and takes `{product}`: the harness always writes the line's text as the English
|
|
188
|
+
* "<Name> product video", so the card keeps only the name from it. `playVideo` is the
|
|
189
|
+
* card's accessible name and takes `{title}`, which is that name. The last four belong to
|
|
190
|
+
* the player: its Close button, the two states of its full-screen toggle, and the line
|
|
191
|
+
* shown in place of a video that cannot be played.
|
|
192
|
+
*/
|
|
193
|
+
productVideo: string;
|
|
194
|
+
productVideoTitle: string;
|
|
195
|
+
playVideo: string;
|
|
196
|
+
closeVideo: string;
|
|
197
|
+
enterFullScreen: string;
|
|
198
|
+
exitFullScreen: string;
|
|
199
|
+
/**
|
|
200
|
+
* BOFF-9697: the site-wide assistant panel (`ExplorePanel`). The tab, view and avatar words are the ones the product
|
|
201
|
+
* apps' assistant already ships in all six locales (Chat, Avatar, Live avatar, Assistant views).
|
|
202
|
+
*/
|
|
203
|
+
panelTitle: string;
|
|
204
|
+
/**
|
|
205
|
+
* BOFF-9796: the panel's title on one product's own assistant (`scope="product"`), "{product} assistant" in each
|
|
206
|
+
* language's own word order. Takes `{product}`. `panelTitle` stays the title wherever no product name is known.
|
|
207
|
+
*/
|
|
208
|
+
panelTitleProduct: string;
|
|
209
|
+
panelViews: string;
|
|
210
|
+
tabChat: string;
|
|
211
|
+
tabAvatar: string;
|
|
212
|
+
closePanel: string;
|
|
213
|
+
liveAvatar: string;
|
|
214
|
+
avatarComingSoon: string;
|
|
215
|
+
continueInChat: string;
|
|
216
|
+
videoUnavailable: string;
|
|
217
|
+
/** Accessible name of the provenance row under an answer. */
|
|
218
|
+
groundedIn: string;
|
|
219
|
+
/** How many sources the answer cites. `sourceCountMany` takes `{count}`. */
|
|
220
|
+
sourceCountOne: string;
|
|
221
|
+
sourceCountMany: string;
|
|
222
|
+
/** What KIND of page a source is, inferred from its URL. */
|
|
223
|
+
sourceKindConcept: string;
|
|
224
|
+
sourceKindDocs: string;
|
|
225
|
+
sourceKindPricing: string;
|
|
226
|
+
sourceKindUseCase: string;
|
|
227
|
+
sourceKindPage: string;
|
|
228
|
+
/**
|
|
229
|
+
* The page's <title> and <meta description>.
|
|
230
|
+
*
|
|
231
|
+
* These are the surface a search result and a browser tab are built from, and they are
|
|
232
|
+
* the LAST place the old product-first framing survived: all 38 sites hard-coded
|
|
233
|
+
* "Explore Burdenoff products with AI" inline, so the tab announced our catalogue on a
|
|
234
|
+
* page that asks the visitor about their problem — and named the wrong brand on 37 of
|
|
235
|
+
* them. `seoTitle` carries no brand: PageHead appends "| {productName}" itself.
|
|
236
|
+
*/
|
|
237
|
+
seoTitle: string;
|
|
238
|
+
seoDescription: string;
|
|
239
|
+
/** Used when the page belongs to a specific product's site. Takes `{product}`. */
|
|
240
|
+
seoDescriptionProduct: string;
|
|
241
|
+
/**
|
|
242
|
+
* BOFF-9796: the meta description of ONE product's own `/explore` (`scope="product"`). Takes `{product}`. Unlike
|
|
243
|
+
* `seoDescriptionProduct`, it promises nothing beyond that product: no "and every other product we build".
|
|
244
|
+
*/
|
|
245
|
+
seoDescriptionScoped: string;
|
|
246
|
+
capabilities: [string, string, string];
|
|
247
|
+
prompts: string[];
|
|
248
|
+
}
|
|
249
|
+
declare function speechLocaleOf(locale: ExploreLocale): string;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* BOFF-9797. The small part of the live avatar that the panel itself needs, whether or not it is ever opened: what a
|
|
253
|
+
* host's `avatar.live` is, whether the live avatar can run on this page at all, and where its requests go.
|
|
254
|
+
*
|
|
255
|
+
* Everything else (the view, its state machine, the requests, the words, the bot check) is a separate chunk that a
|
|
256
|
+
* site only downloads when its visitor first opens the Avatar view (see `explore-avatar-live.tsx`). That is why this
|
|
257
|
+
* file is separate and kept to a few lines: it is the only part of the live avatar in the package root for a site that
|
|
258
|
+
* does not pass `avatar.live`, and the part of it that decides, without loading anything, whether the chunk is wanted.
|
|
259
|
+
* Types only, plus plain functions: nothing here imports a component, a context or a string table.
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* BOFF-9797. A host's opt-in to the live avatar on its panel's Avatar tab. Every field is required; a config that is
|
|
264
|
+
* incomplete leaves the tab as it was (and a warning in the console).
|
|
265
|
+
*/
|
|
266
|
+
interface ExplorePanelAvatarLive {
|
|
267
|
+
/** The site, as the live avatar service knows it: `healthybowl`. */
|
|
268
|
+
site: string;
|
|
269
|
+
/**
|
|
270
|
+
* Loads the live avatar's room module: `() => import('@burdenoff/website-sdk/avatar-live')`. Called only after the
|
|
271
|
+
* visitor presses Start on the consent card, never on page load or on opening the tab. That entry needs the
|
|
272
|
+
* package's optional peer dependency for media rooms (see the README).
|
|
273
|
+
*/
|
|
274
|
+
load: () => Promise<AvatarLiveModule>;
|
|
275
|
+
/** The site's Cloudflare Turnstile site key, for the bot check that runs when the visitor presses Start. */
|
|
276
|
+
turnstileSiteKey: string;
|
|
277
|
+
/** The version of the suggested-question list the panel shows (its `examplePrompts`), such as `hb-en-1`. */
|
|
278
|
+
manifestVersion: string;
|
|
279
|
+
}
|
|
280
|
+
/** What the live avatar reads of the panel's conversation: the transcript, whether it is read-only, and the token. */
|
|
281
|
+
type AvatarConversation = Pick<UseExploreChatResult, "messages" | "isSharedView" | "getConversationToken">;
|
|
282
|
+
|
|
283
|
+
export { type AvatarConversation as A, type ExplorePanelAvatarLive as E, type ExploreLocale as a, EXPLORE_LOCALES as b, type ExploreStrings as c, speechLocaleOf as s };
|
|
@@ -350,4 +350,4 @@ declare const EXPLORE_ESCALATION_NOTE_SOFT_MAX = 2000;
|
|
|
350
350
|
*/
|
|
351
351
|
declare function looksLikeDeliverableEmail(value: string): boolean;
|
|
352
352
|
|
|
353
|
-
export { looksLikeDeliverableEmail as A, type
|
|
353
|
+
export { looksLikeDeliverableEmail as A, type ExploreCatalog as E, SEND_EXPLORE_MESSAGE_MUTATION as S, type ExploreMessage as a, type ExploreFeedbackRating as b, type ExploreFeedbackReason as c, type ExploreLimits as d, type ExploreProduct as e, type ExploreReference as f, ESCALATE_EXPLORE_CONVERSATION_MUTATION as g, EXPLORE_CATALOG_QUERY as h, EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS as i, EXPLORE_ESCALATION_NOTE_SOFT_MAX as j, EXPLORE_MESSAGE_QUERY as k, type EscalateExploreConversationInput as l, type EscalateExploreConversationResult as m, type ExploreCatalogQueryData as n, type ExploreConceptHighlight as o, type ExploreConversation as p, type ExploreCtaKind as q, type ExploreCtaLink as r, type ExploreErrorCode as s, type ExploreEscalation as t, type ExploreMessageQueryData as u, type ExploreMessageRole as v, type ExploreMessageStatus as w, type SendExploreMessageInput as x, type SendExploreMessageMutationData as y, type SendExploreMessageResult as z };
|
|
@@ -350,4 +350,4 @@ declare const EXPLORE_ESCALATION_NOTE_SOFT_MAX = 2000;
|
|
|
350
350
|
*/
|
|
351
351
|
declare function looksLikeDeliverableEmail(value: string): boolean;
|
|
352
352
|
|
|
353
|
-
export { looksLikeDeliverableEmail as A, type
|
|
353
|
+
export { looksLikeDeliverableEmail as A, type ExploreCatalog as E, SEND_EXPLORE_MESSAGE_MUTATION as S, type ExploreMessage as a, type ExploreFeedbackRating as b, type ExploreFeedbackReason as c, type ExploreLimits as d, type ExploreProduct as e, type ExploreReference as f, ESCALATE_EXPLORE_CONVERSATION_MUTATION as g, EXPLORE_CATALOG_QUERY as h, EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS as i, EXPLORE_ESCALATION_NOTE_SOFT_MAX as j, EXPLORE_MESSAGE_QUERY as k, type EscalateExploreConversationInput as l, type EscalateExploreConversationResult as m, type ExploreCatalogQueryData as n, type ExploreConceptHighlight as o, type ExploreConversation as p, type ExploreCtaKind as q, type ExploreCtaLink as r, type ExploreErrorCode as s, type ExploreEscalation as t, type ExploreMessageQueryData as u, type ExploreMessageRole as v, type ExploreMessageStatus as w, type SendExploreMessageInput as x, type SendExploreMessageMutationData as y, type SendExploreMessageResult as z };
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, c as ExploreEscalateOutcome, d as ExploreEscalateResult, F as FALLBACK_EXPLORE_LIMITS, U as UseExploreChatOptions, e as UseExploreChatResult, f as
|
|
2
|
-
|
|
1
|
+
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, c as ExploreEscalateOutcome, d as ExploreEscalateResult, F as FALLBACK_EXPLORE_LIMITS, U as UseExploreChatOptions, e as UseExploreChatResult, f as classifyExploreError, u as useExploreChat } from '../use-explore-chat-zRuoAin6.mjs';
|
|
2
|
+
export { U as UseSpeechOutputOptions, a as UseSpeechOutputResult, s as stopSpeaking, u as useProgressiveReveal, b as useSpeechOutput } from '../use-progressive-reveal-ppicEgzZ.mjs';
|
|
3
|
+
import '../explore-types-Bb2Ih3d8.mjs';
|
|
3
4
|
|
|
4
5
|
interface UseSpeechInputOptions {
|
|
5
6
|
/** Receives settled text as it is recognised. Append it to the draft. */
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, c as ExploreEscalateOutcome, d as ExploreEscalateResult, F as FALLBACK_EXPLORE_LIMITS, U as UseExploreChatOptions, e as UseExploreChatResult, f as
|
|
2
|
-
|
|
1
|
+
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, c as ExploreEscalateOutcome, d as ExploreEscalateResult, F as FALLBACK_EXPLORE_LIMITS, U as UseExploreChatOptions, e as UseExploreChatResult, f as classifyExploreError, u as useExploreChat } from '../use-explore-chat-DunjG-3p.js';
|
|
2
|
+
export { U as UseSpeechOutputOptions, a as UseSpeechOutputResult, s as stopSpeaking, u as useProgressiveReveal, b as useSpeechOutput } from '../use-progressive-reveal-ppicEgzZ.js';
|
|
3
|
+
import '../explore-types-Bb2Ih3d8.js';
|
|
3
4
|
|
|
4
5
|
interface UseSpeechInputOptions {
|
|
5
6
|
/** Receives settled text as it is recognised. Append it to the draft. */
|
package/dist/hooks/index.js
CHANGED
|
@@ -1699,6 +1699,10 @@ function useExploreChat(options = {}) {
|
|
|
1699
1699
|
[client, productId]
|
|
1700
1700
|
);
|
|
1701
1701
|
const canEscalate = hasConversation && !isSharedView;
|
|
1702
|
+
const getConversationToken = react.useCallback(
|
|
1703
|
+
() => conversationTokenRef.current,
|
|
1704
|
+
[]
|
|
1705
|
+
);
|
|
1702
1706
|
return {
|
|
1703
1707
|
phase,
|
|
1704
1708
|
catalog,
|
|
@@ -1723,7 +1727,8 @@ function useExploreChat(options = {}) {
|
|
|
1723
1727
|
escalate,
|
|
1724
1728
|
canEscalate,
|
|
1725
1729
|
createShareLink,
|
|
1726
|
-
isSharedView
|
|
1730
|
+
isSharedView,
|
|
1731
|
+
getConversationToken
|
|
1727
1732
|
};
|
|
1728
1733
|
}
|
|
1729
1734
|
var optimisticCounter = 0;
|