@burdenoff/website-sdk 2026.922.2 → 2026.922.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, useMemo, useState, useRef, useCallback, useEffect, useContext } from 'react';
3
- import { Sparkles, RotateCcw, Link2, History, Trash2, Paperclip, X, Mic, Square, ArrowUp, BookOpenText, Layers, TriangleAlert, ChevronLeft, ChevronRight, ExternalLink } from 'lucide-react';
3
+ import { Sparkles, RotateCcw, Link2, History, Trash2, Paperclip, X, Mic, Square, ArrowUp, BookOpenText, Layers, TriangleAlert, ChevronLeft, ChevronRight, ExternalLink, ThumbsUp, ThumbsDown } from 'lucide-react';
4
4
  import ReactMarkdown from 'react-markdown';
5
5
  import rehypeSanitize from 'rehype-sanitize';
6
6
  import remarkGfm from 'remark-gfm';
@@ -56,10 +56,30 @@ var EN = {
56
56
  noAnswer: "I couldn't find this in our documentation, so the answer below is not grounded in a source. Try rephrasing, or",
57
57
  answerDidNotArrive: "That answer didn't come through. Try asking again.",
58
58
  askHuman: "ask a human",
59
+ // An offer, not a demand: this row sits under every answer on 38 marketing sites, so the
60
+ // wording has to be shruggable. "Was this helpful?" invites; "Please rate this answer"
61
+ // conscripts.
62
+ feedbackPrompt: "Was this helpful?",
63
+ feedbackHelpful: "Helpful",
64
+ feedbackNotHelpful: "Not helpful",
65
+ feedbackReasonTitle: "What was off?",
66
+ feedbackReasonInaccurate: "Inaccurate",
67
+ feedbackReasonIncomplete: "Incomplete",
68
+ feedbackReasonOffTopic: "Off topic",
69
+ feedbackReasonHardToFollow: "Hard to follow",
70
+ feedbackReasonOther: "Something else",
71
+ feedbackCommentPlaceholder: "Add a detail (optional)",
72
+ feedbackSend: "Send",
73
+ feedbackDismiss: "Dismiss",
74
+ feedbackThanks: "Thanks \u2014 that helps.",
75
+ feedbackNotSent: "That didn't send.",
59
76
  prevSuggestion: "Previous suggestion",
60
77
  nextSuggestion: "Next suggestion",
61
78
  conceptIllustration: "Concept illustration",
62
79
  opensInNewTab: "opens in a new tab",
80
+ seoTitle: "Describe a problem, get an answer",
81
+ seoDescription: "Describe the problem you're facing in your own words and get an answer drawn from our product documentation, with links to the exact pages it came from.",
82
+ seoDescriptionProduct: "Describe the problem you're facing in your own words and get an answer drawn from {product}'s documentation \u2014 and every other product we build \u2014 with links to the exact pages it came from.",
63
83
  capabilities: [
64
84
  "Grounded in our own docs",
65
85
  "Compare across the ecosystem",
@@ -107,10 +127,27 @@ var ZH = {
107
127
  noAnswer: "\u6211\u5728\u6587\u6863\u4E2D\u6CA1\u6709\u627E\u5230\u76F8\u5173\u5185\u5BB9\uFF0C\u4E0B\u9762\u7684\u56DE\u7B54\u6CA1\u6709\u6765\u6E90\u652F\u6301\u3002\u8BF7\u6362\u4E2A\u8BF4\u6CD5\uFF0C\u6216",
108
128
  answerDidNotArrive: "\u8FD9\u6761\u56DE\u7B54\u6CA1\u6709\u8FD4\u56DE\u3002\u8BF7\u518D\u95EE\u4E00\u6B21\u3002",
109
129
  askHuman: "\u8054\u7CFB\u6211\u4EEC",
130
+ feedbackPrompt: "\u8FD9\u4E2A\u56DE\u7B54\u6709\u5E2E\u52A9\u5417\uFF1F",
131
+ feedbackHelpful: "\u6709\u5E2E\u52A9",
132
+ feedbackNotHelpful: "\u6CA1\u6709\u5E2E\u52A9",
133
+ feedbackReasonTitle: "\u54EA\u91CC\u4E0D\u5BF9\uFF1F",
134
+ feedbackReasonInaccurate: "\u4E0D\u51C6\u786E",
135
+ feedbackReasonIncomplete: "\u4E0D\u5B8C\u6574",
136
+ feedbackReasonOffTopic: "\u7B54\u975E\u6240\u95EE",
137
+ feedbackReasonHardToFollow: "\u770B\u4E0D\u592A\u61C2",
138
+ feedbackReasonOther: "\u5176\u4ED6\u539F\u56E0",
139
+ feedbackCommentPlaceholder: "\u8865\u5145\u8BF4\u660E\uFF08\u53EF\u9009\uFF09",
140
+ feedbackSend: "\u63D0\u4EA4",
141
+ feedbackDismiss: "\u5173\u95ED",
142
+ feedbackThanks: "\u8C22\u8C22\uFF0C\u8FD9\u5BF9\u6211\u4EEC\u5F88\u6709\u5E2E\u52A9\u3002",
143
+ feedbackNotSent: "\u6CA1\u6709\u63D0\u4EA4\u6210\u529F\u3002",
110
144
  prevSuggestion: "\u4E0A\u4E00\u4E2A\u5EFA\u8BAE",
111
145
  nextSuggestion: "\u4E0B\u4E00\u4E2A\u5EFA\u8BAE",
112
146
  conceptIllustration: "\u6982\u5FF5\u793A\u610F\u56FE",
113
147
  opensInNewTab: "\u5728\u65B0\u6807\u7B7E\u9875\u4E2D\u6253\u5F00",
148
+ seoTitle: "\u63CF\u8FF0\u95EE\u9898\uFF0C\u83B7\u5F97\u7B54\u6848",
149
+ seoDescription: "\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u63CF\u8FF0\u9047\u5230\u7684\u95EE\u9898\uFF0C\u5373\u53EF\u83B7\u5F97\u6765\u81EA\u6211\u4EEC\u4EA7\u54C1\u6587\u6863\u7684\u56DE\u7B54\uFF0C\u5E76\u9644\u4E0A\u7B54\u6848\u51FA\u5904\u7684\u9875\u9762\u94FE\u63A5\u3002",
150
+ seoDescriptionProduct: "\u7528\u4F60\u81EA\u5DF1\u7684\u8BDD\u63CF\u8FF0\u9047\u5230\u7684\u95EE\u9898\uFF0C\u5373\u53EF\u83B7\u5F97\u6765\u81EA {product} \u53CA\u6211\u4EEC\u5176\u4ED6\u4EA7\u54C1\u6587\u6863\u7684\u56DE\u7B54\uFF0C\u5E76\u9644\u4E0A\u7B54\u6848\u51FA\u5904\u7684\u9875\u9762\u94FE\u63A5\u3002",
114
151
  capabilities: ["\u57FA\u4E8E\u6211\u4EEC\u81EA\u5DF1\u7684\u6587\u6863", "\u8DE8\u4EA7\u54C1\u5BF9\u6BD4", "\u76F4\u8FBE\u6B63\u786E\u7684\u9875\u9762"],
115
152
  prompts: [
116
153
  "\u6BCF\u95E8\u8BFE\u7A0B\u90FD\u8BB0\u5728\u4E0D\u540C\u7684\u8868\u683C\u91CC\u3002",
@@ -154,10 +191,27 @@ var HI = {
154
191
  noAnswer: "\u092F\u0939 \u092E\u0941\u091D\u0947 \u0939\u092E\u093E\u0930\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092E\u0947\u0902 \u0928\u0939\u0940\u0902 \u092E\u093F\u0932\u093E, \u0907\u0938\u0932\u093F\u090F \u0928\u0940\u091A\u0947 \u0926\u093F\u092F\u093E \u0909\u0924\u094D\u0924\u0930 \u0915\u093F\u0938\u0940 \u0938\u094D\u0930\u094B\u0924 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924 \u0928\u0939\u0940\u0902 \u0939\u0948\u0964 \u0926\u0942\u0938\u0930\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092A\u0942\u091B\u0947\u0902, \u092F\u093E",
155
192
  answerDidNotArrive: "\u0935\u0939 \u0909\u0924\u094D\u0924\u0930 \u0928\u0939\u0940\u0902 \u0906 \u0938\u0915\u093E\u0964 \u0915\u0943\u092A\u092F\u093E \u0926\u094B\u092C\u093E\u0930\u093E \u092A\u0942\u091B\u0947\u0902\u0964",
156
193
  askHuman: "\u0939\u092E\u0938\u0947 \u0938\u0902\u092A\u0930\u094D\u0915 \u0915\u0930\u0947\u0902",
194
+ feedbackPrompt: "\u0915\u094D\u092F\u093E \u092F\u0939 \u0909\u0924\u094D\u0924\u0930 \u092E\u0926\u0926\u0917\u093E\u0930 \u0925\u093E?",
195
+ feedbackHelpful: "\u092E\u0926\u0926\u0917\u093E\u0930",
196
+ feedbackNotHelpful: "\u092E\u0926\u0926\u0917\u093E\u0930 \u0928\u0939\u0940\u0902",
197
+ feedbackReasonTitle: "\u0915\u094D\u092F\u093E \u0920\u0940\u0915 \u0928\u0939\u0940\u0902 \u0925\u093E?",
198
+ feedbackReasonInaccurate: "\u0917\u093C\u0932\u0924 \u091C\u093E\u0928\u0915\u093E\u0930\u0940",
199
+ feedbackReasonIncomplete: "\u0905\u0927\u0942\u0930\u093E",
200
+ feedbackReasonOffTopic: "\u0935\u093F\u0937\u092F \u0938\u0947 \u0939\u091F\u0915\u0930",
201
+ feedbackReasonHardToFollow: "\u0938\u092E\u091D\u0928\u0947 \u092E\u0947\u0902 \u092E\u0941\u0936\u094D\u0915\u093F\u0932",
202
+ feedbackReasonOther: "\u0915\u0941\u091B \u0914\u0930",
203
+ feedbackCommentPlaceholder: "\u0915\u0941\u091B \u0914\u0930 \u092C\u0924\u093E\u090F\u0902 (\u0935\u0948\u0915\u0932\u094D\u092A\u093F\u0915)",
204
+ feedbackSend: "\u092D\u0947\u091C\u0947\u0902",
205
+ feedbackDismiss: "\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
206
+ feedbackThanks: "\u0927\u0928\u094D\u092F\u0935\u093E\u0926, \u0907\u0938\u0938\u0947 \u092E\u0926\u0926 \u092E\u093F\u0932\u0924\u0940 \u0939\u0948\u0964",
207
+ feedbackNotSent: "\u092F\u0939 \u092D\u0947\u091C\u093E \u0928\u0939\u0940\u0902 \u091C\u093E \u0938\u0915\u093E\u0964",
157
208
  prevSuggestion: "\u092A\u093F\u091B\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
158
209
  nextSuggestion: "\u0905\u0917\u0932\u093E \u0938\u0941\u091D\u093E\u0935",
159
210
  conceptIllustration: "\u0905\u0935\u0927\u093E\u0930\u0923\u093E \u091A\u093F\u0924\u094D\u0930\u0923",
160
211
  opensInNewTab: "\u0928\u090F \u091F\u0948\u092C \u092E\u0947\u0902 \u0916\u0941\u0932\u0924\u093E \u0939\u0948",
212
+ seoTitle: "\u0938\u092E\u0938\u094D\u092F\u093E \u092C\u0924\u093E\u090F\u0902, \u091C\u0935\u093E\u092C \u092A\u093E\u090F\u0902",
213
+ seoDescription: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0905\u092A\u0928\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092C\u0924\u093E\u090F\u0902 \u0914\u0930 \u0939\u092E\u093E\u0930\u0947 \u0909\u0924\u094D\u092A\u093E\u0926 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u0938\u0947 \u0932\u093F\u092F\u093E \u0917\u092F\u093E \u091C\u0935\u093E\u092C \u092A\u093E\u090F\u0902, \u0938\u093E\u0925 \u092E\u0947\u0902 \u0909\u0928\u094D\u0939\u0940\u0902 \u092A\u0928\u094D\u0928\u094B\u0902 \u0915\u0947 \u0932\u093F\u0902\u0915 \u091C\u0939\u093E\u0901 \u0938\u0947 \u0935\u0939 \u0906\u092F\u093E \u0939\u0948\u0964",
214
+ seoDescriptionProduct: "\u0905\u092A\u0928\u0940 \u0938\u092E\u0938\u094D\u092F\u093E \u0905\u092A\u0928\u0947 \u0936\u092C\u094D\u0926\u094B\u0902 \u092E\u0947\u0902 \u092C\u0924\u093E\u090F\u0902 \u0914\u0930 {product} \u0924\u0925\u093E \u0939\u092E\u093E\u0930\u0947 \u092C\u093E\u0915\u0940 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u0938\u0947 \u0932\u093F\u092F\u093E \u0917\u092F\u093E \u091C\u0935\u093E\u092C \u092A\u093E\u090F\u0902, \u0938\u093E\u0925 \u092E\u0947\u0902 \u0909\u0928\u094D\u0939\u0940\u0902 \u092A\u0928\u094D\u0928\u094B\u0902 \u0915\u0947 \u0932\u093F\u0902\u0915 \u091C\u0939\u093E\u0901 \u0938\u0947 \u0935\u0939 \u0906\u092F\u093E \u0939\u0948\u0964",
161
215
  capabilities: [
162
216
  "\u0939\u092E\u093E\u0930\u0947 \u0905\u092A\u0928\u0947 \u0926\u0938\u094D\u0924\u093E\u0935\u0947\u091C\u093C\u094B\u0902 \u092A\u0930 \u0906\u0927\u093E\u0930\u093F\u0924",
163
217
  "\u0938\u092D\u0940 \u0909\u0924\u094D\u092A\u093E\u0926\u094B\u0902 \u0915\u0940 \u0924\u0941\u0932\u0928\u093E \u0915\u0930\u0947\u0902",
@@ -205,10 +259,27 @@ var ES = {
205
259
  noAnswer: "No he encontrado esto en nuestra documentaci\xF3n, as\xED que la respuesta de abajo no se apoya en ninguna fuente. Prueba a reformularla, o",
206
260
  answerDidNotArrive: "Esa respuesta no lleg\xF3. Int\xE9ntalo de nuevo.",
207
261
  askHuman: "habla con una persona",
262
+ feedbackPrompt: "\xBFTe ha servido?",
263
+ feedbackHelpful: "Me sirve",
264
+ feedbackNotHelpful: "No me sirve",
265
+ feedbackReasonTitle: "\xBFQu\xE9 ha fallado?",
266
+ feedbackReasonInaccurate: "Es inexacta",
267
+ feedbackReasonIncomplete: "Est\xE1 incompleta",
268
+ feedbackReasonOffTopic: "No viene al caso",
269
+ feedbackReasonHardToFollow: "Cuesta seguirla",
270
+ feedbackReasonOther: "Otra cosa",
271
+ feedbackCommentPlaceholder: "A\xF1ade un detalle (opcional)",
272
+ feedbackSend: "Enviar",
273
+ feedbackDismiss: "Cerrar",
274
+ feedbackThanks: "Gracias, nos sirve.",
275
+ feedbackNotSent: "No se ha podido enviar.",
208
276
  prevSuggestion: "Sugerencia anterior",
209
277
  nextSuggestion: "Sugerencia siguiente",
210
278
  conceptIllustration: "Ilustraci\xF3n del concepto",
211
279
  opensInNewTab: "se abre en una pesta\xF1a nueva",
280
+ seoTitle: "Describe un problema y obt\xE9n una respuesta",
281
+ seoDescription: "Describe con tus palabras el problema que tienes y recibe una respuesta extra\xEDda de la documentaci\xF3n de nuestros productos, con enlaces a las p\xE1ginas exactas de las que procede.",
282
+ seoDescriptionProduct: "Describe con tus palabras el problema que tienes y recibe una respuesta extra\xEDda de la documentaci\xF3n de {product} y del resto de nuestros productos, con enlaces a las p\xE1ginas exactas de las que procede.",
212
283
  capabilities: [
213
284
  "Basado en nuestra documentaci\xF3n",
214
285
  "Compara todo el ecosistema",
@@ -256,10 +327,27 @@ var AR = {
256
327
  noAnswer: "\u0644\u0645 \u0623\u062C\u062F \u0647\u0630\u0627 \u0641\u064A \u0648\u062B\u0627\u0626\u0642\u0646\u0627\u060C \u0644\u0630\u0627 \u0641\u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0623\u062F\u0646\u0627\u0647 \u063A\u064A\u0631 \u0645\u0633\u062A\u0646\u062F\u0629 \u0625\u0644\u0649 \u0645\u0635\u062F\u0631. \u062D\u0627\u0648\u0644 \u0625\u0639\u0627\u062F\u0629 \u0627\u0644\u0635\u064A\u0627\u063A\u0629\u060C \u0623\u0648",
257
328
  answerDidNotArrive: "\u0644\u0645 \u062A\u0635\u0644 \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629. \u064A\u0631\u062C\u0649 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649.",
258
329
  askHuman: "\u062A\u062D\u062F\u0651\u062B \u0625\u0644\u0649 \u0634\u062E\u0635",
330
+ feedbackPrompt: "\u0647\u0644 \u0643\u0627\u0646\u062A \u0647\u0630\u0647 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0645\u0641\u064A\u062F\u0629\u061F",
331
+ feedbackHelpful: "\u0645\u0641\u064A\u062F\u0629",
332
+ feedbackNotHelpful: "\u063A\u064A\u0631 \u0645\u0641\u064A\u062F\u0629",
333
+ feedbackReasonTitle: "\u0645\u0627 \u0627\u0644\u062E\u0637\u0623 \u0641\u064A\u0647\u0627\u061F",
334
+ feedbackReasonInaccurate: "\u063A\u064A\u0631 \u062F\u0642\u064A\u0642\u0629",
335
+ feedbackReasonIncomplete: "\u0646\u0627\u0642\u0635\u0629",
336
+ feedbackReasonOffTopic: "\u062E\u0627\u0631\u062C \u0627\u0644\u0645\u0648\u0636\u0648\u0639",
337
+ feedbackReasonHardToFollow: "\u0635\u0639\u0628\u0629 \u0627\u0644\u0641\u0647\u0645",
338
+ feedbackReasonOther: "\u0634\u064A\u0621 \u0622\u062E\u0631",
339
+ feedbackCommentPlaceholder: "\u0623\u0636\u0641 \u062A\u0641\u0635\u064A\u0644\u0627\u064B (\u0627\u062E\u062A\u064A\u0627\u0631\u064A)",
340
+ feedbackSend: "\u0625\u0631\u0633\u0627\u0644",
341
+ feedbackDismiss: "\u0625\u063A\u0644\u0627\u0642",
342
+ feedbackThanks: "\u0634\u0643\u0631\u064B\u0627\u060C \u0647\u0630\u0627 \u064A\u0633\u0627\u0639\u062F\u0646\u0627.",
343
+ feedbackNotSent: "\u0644\u0645 \u064A\u062A\u0645 \u0627\u0644\u0625\u0631\u0633\u0627\u0644.",
259
344
  prevSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u0633\u0627\u0628\u0642",
260
345
  nextSuggestion: "\u0627\u0644\u0627\u0642\u062A\u0631\u0627\u062D \u0627\u0644\u062A\u0627\u0644\u064A",
261
346
  conceptIllustration: "\u0631\u0633\u0645 \u062A\u0648\u0636\u064A\u062D\u064A \u0644\u0644\u0645\u0641\u0647\u0648\u0645",
262
347
  opensInNewTab: "\u064A\u064F\u0641\u062A\u062D \u0641\u064A \u0639\u0644\u0627\u0645\u0629 \u062A\u0628\u0648\u064A\u0628 \u062C\u062F\u064A\u062F\u0629",
348
+ seoTitle: "\u0635\u0641 \u0645\u0634\u0643\u0644\u062A\u0643 \u0648\u0627\u062D\u0635\u0644 \u0639\u0644\u0649 \u0625\u062C\u0627\u0628\u0629",
349
+ seoDescription: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0627\u0644\u062A\u064A \u062A\u0648\u0627\u062C\u0647\u0647\u0627 \u0628\u0643\u0644\u0645\u0627\u062A\u0643 \u0648\u0627\u062D\u0635\u0644 \u0639\u0644\u0649 \u0625\u062C\u0627\u0628\u0629 \u0645\u0633\u062A\u0645\u062F\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642 \u0645\u0646\u062A\u062C\u0627\u062A\u0646\u0627\u060C \u0645\u0639 \u0631\u0648\u0627\u0628\u0637 \u0625\u0644\u0649 \u0627\u0644\u0635\u0641\u062D\u0627\u062A \u0627\u0644\u062A\u064A \u062C\u0627\u0621\u062A \u0645\u0646\u0647\u0627.",
350
+ seoDescriptionProduct: "\u0635\u0641 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0627\u0644\u062A\u064A \u062A\u0648\u0627\u062C\u0647\u0647\u0627 \u0628\u0643\u0644\u0645\u0627\u062A\u0643 \u0648\u0627\u062D\u0635\u0644 \u0639\u0644\u0649 \u0625\u062C\u0627\u0628\u0629 \u0645\u0633\u062A\u0645\u062F\u0629 \u0645\u0646 \u0648\u062B\u0627\u0626\u0642 {product} \u0648\u0628\u0642\u064A\u0629 \u0645\u0646\u062A\u062C\u0627\u062A\u0646\u0627\u060C \u0645\u0639 \u0631\u0648\u0627\u0628\u0637 \u0625\u0644\u0649 \u0627\u0644\u0635\u0641\u062D\u0627\u062A \u0627\u0644\u062A\u064A \u062C\u0627\u0621\u062A \u0645\u0646\u0647\u0627.",
263
351
  capabilities: [
264
352
  "\u0645\u0628\u0646\u064A \u0639\u0644\u0649 \u0648\u062B\u0627\u0626\u0642\u0646\u0627",
265
353
  "\u0642\u0627\u0631\u0646 \u0639\u0628\u0631 \u0627\u0644\u0645\u0646\u0638\u0648\u0645\u0629",
@@ -307,10 +395,27 @@ var TA = {
307
395
  noAnswer: "\u0B87\u0BA4\u0BC1 \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0B95\u0BBF\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8, \u0B8E\u0BA9\u0BB5\u0BC7 \u0B95\u0BC0\u0BB4\u0BC7 \u0B89\u0BB3\u0BCD\u0BB3 \u0BAA\u0BA4\u0BBF\u0BB2\u0BC1\u0B95\u0BCD\u0B95\u0BC1 \u0BAE\u0BC2\u0BB2\u0BAE\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8. \u0BB5\u0BC7\u0BB1\u0BC1 \u0BB5\u0B95\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD \u0B95\u0BC7\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0B85\u0BB2\u0BCD\u0BB2\u0BA4\u0BC1",
308
396
  answerDidNotArrive: "\u0B85\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BB5\u0BB0\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8. \u0BAE\u0BC0\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD \u0B95\u0BC7\u0B9F\u0BCD\u0B9F\u0BC1\u0BAA\u0BCD \u0BAA\u0BBE\u0BB0\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD.",
309
397
  askHuman: "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B9F\u0BB0\u0BCD\u0BAA\u0BC1 \u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
398
+ feedbackPrompt: "\u0B87\u0BA8\u0BCD\u0BA4\u0BAA\u0BCD \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BAA\u0BAF\u0BA9\u0BC1\u0BB3\u0BCD\u0BB3\u0BA4\u0BBE\u0B95 \u0B87\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BA4\u0BBE?",
399
+ feedbackHelpful: "\u0BAA\u0BAF\u0BA9\u0BC1\u0BB3\u0BCD\u0BB3\u0BA4\u0BC1",
400
+ feedbackNotHelpful: "\u0BAA\u0BAF\u0BA9\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8",
401
+ feedbackReasonTitle: "\u0B8E\u0BA9\u0BCD\u0BA9 \u0B9A\u0BB0\u0BBF\u0BAF\u0BBE\u0B95 \u0B87\u0BB2\u0BCD\u0BB2\u0BC8?",
402
+ feedbackReasonInaccurate: "\u0BA4\u0BB5\u0BB1\u0BBE\u0BA9 \u0BA4\u0B95\u0BB5\u0BB2\u0BCD",
403
+ feedbackReasonIncomplete: "\u0BAE\u0BC1\u0BB4\u0BC1\u0BAE\u0BC8\u0BAF\u0BB1\u0BCD\u0BB1\u0BA4\u0BC1",
404
+ feedbackReasonOffTopic: "\u0BA4\u0BB2\u0BC8\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BCD\u0B95\u0BC1 \u0B85\u0BAA\u0BCD\u0BAA\u0BBE\u0BB1\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1",
405
+ feedbackReasonHardToFollow: "\u0BAA\u0BC1\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0B95\u0BCA\u0BB3\u0BCD\u0BB3 \u0B95\u0B9F\u0BBF\u0BA9\u0BAE\u0BCD",
406
+ feedbackReasonOther: "\u0BB5\u0BC7\u0BB1\u0BC1 \u0B8F\u0BA4\u0BCB",
407
+ feedbackCommentPlaceholder: "\u0BAE\u0BC7\u0BB2\u0BC1\u0BAE\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BAE\u0BCD (\u0BB5\u0BBF\u0BB0\u0BC1\u0BAA\u0BCD\u0BAA\u0BAE\u0BCD)",
408
+ feedbackSend: "\u0B85\u0BA9\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1",
409
+ feedbackDismiss: "\u0BAE\u0BC2\u0B9F\u0BC1",
410
+ feedbackThanks: "\u0BA8\u0BA9\u0BCD\u0BB1\u0BBF, \u0B87\u0BA4\u0BC1 \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BC1 \u0B89\u0BA4\u0BB5\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1.",
411
+ feedbackNotSent: "\u0B85\u0BA9\u0BC1\u0BAA\u0BCD\u0BAA \u0BAE\u0BC1\u0B9F\u0BBF\u0BAF\u0BB5\u0BBF\u0BB2\u0BCD\u0BB2\u0BC8.",
310
412
  prevSuggestion: "\u0BAE\u0BC1\u0BA8\u0BCD\u0BA4\u0BC8\u0BAF \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
311
413
  nextSuggestion: "\u0B85\u0B9F\u0BC1\u0BA4\u0BCD\u0BA4 \u0BAA\u0BB0\u0BBF\u0BA8\u0BCD\u0BA4\u0BC1\u0BB0\u0BC8",
312
414
  conceptIllustration: "\u0B95\u0BB0\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1 \u0BB5\u0BBF\u0BB3\u0B95\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0B9F\u0BAE\u0BCD",
313
415
  opensInNewTab: "\u0BAA\u0BC1\u0BA4\u0BBF\u0BAF \u0BA4\u0BBE\u0BB5\u0BB2\u0BBF\u0BB2\u0BCD \u0BA4\u0BBF\u0BB1\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD",
416
+ seoTitle: "\u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD, \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BAA\u0BC6\u0BB1\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
417
+ seoDescription: "\u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0BAE\u0BCD \u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0BB5\u0BBE\u0BB0\u0BCD\u0BA4\u0BCD\u0BA4\u0BC8\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD; \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1 \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0B95\u0BBF\u0B9F\u0BC8\u0B95\u0BCD\u0B95\u0BC1\u0BAE\u0BCD, \u0B85\u0BA4\u0BC1 \u0BB5\u0BA8\u0BCD\u0BA4 \u0BAA\u0B95\u0BCD\u0B95\u0B99\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B87\u0BA3\u0BC8\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC1\u0B9F\u0BA9\u0BCD.",
418
+ seoDescriptionProduct: "{product} \u0BAE\u0BB1\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD \u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0BAA\u0BBF\u0BB1 \u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BBF\u0BA9\u0BCD \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BB2\u0BBF\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1 \u0BAA\u0BA4\u0BBF\u0BB2\u0BCD \u0BAA\u0BC6\u0BB1, \u0BA8\u0BC0\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B8E\u0BA4\u0BBF\u0BB0\u0BCD\u0B95\u0BCA\u0BB3\u0BCD\u0BB3\u0BC1\u0BAE\u0BCD \u0B9A\u0BBF\u0B95\u0BCD\u0B95\u0BB2\u0BC8 \u0B89\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0BB5\u0BBE\u0BB0\u0BCD\u0BA4\u0BCD\u0BA4\u0BC8\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0BB5\u0BBF\u0BB5\u0BB0\u0BBF\u0BAF\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u2014 \u0B85\u0BA4\u0BC1 \u0BB5\u0BA8\u0BCD\u0BA4 \u0BAA\u0B95\u0BCD\u0B95\u0B99\u0BCD\u0B95\u0BB3\u0BC1\u0B95\u0BCD\u0B95\u0BBE\u0BA9 \u0B87\u0BA3\u0BC8\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC1\u0B9F\u0BA9\u0BCD.",
314
419
  capabilities: [
315
420
  "\u0B8E\u0B99\u0BCD\u0B95\u0BB3\u0BCD \u0B9A\u0BCA\u0BA8\u0BCD\u0BA4 \u0B86\u0BB5\u0BA3\u0B99\u0BCD\u0B95\u0BB3\u0BBF\u0BA9\u0BCD \u0B85\u0B9F\u0BBF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC8\u0BAF\u0BBF\u0BB2\u0BCD",
316
421
  "\u0BA4\u0BAF\u0BBE\u0BB0\u0BBF\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BC8 \u0B92\u0BAA\u0BCD\u0BAA\u0BBF\u0B9F\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
@@ -351,6 +456,171 @@ function exploreStrings(locale) {
351
456
  function fill(template, values) {
352
457
  return template.replace(/\{(\w+)\}/g, (match, key) => values[key] ?? match);
353
458
  }
459
+
460
+ // src/components/explore-types.ts
461
+ var EXPLORE_FEEDBACK_REASONS = [
462
+ "INACCURATE",
463
+ "INCOMPLETE",
464
+ "OFF_TOPIC",
465
+ "HARD_TO_FOLLOW",
466
+ "OTHER"
467
+ ];
468
+ var EXPLORE_MESSAGE_FIELDS = (
469
+ /* GraphQL */
470
+ `
471
+ id
472
+ conversationId
473
+ role
474
+ status
475
+ content
476
+ partialContent
477
+ activity
478
+ references {
479
+ url
480
+ title
481
+ description
482
+ product
483
+ imageUrl
484
+ index
485
+ }
486
+ ctas {
487
+ kind
488
+ label
489
+ url
490
+ product
491
+ }
492
+ followUps
493
+ answered
494
+ attachments {
495
+ name
496
+ mimeType
497
+ size
498
+ textExtracted
499
+ }
500
+ errorCode
501
+ createdAt
502
+ completedAt
503
+ `
504
+ );
505
+ var EXPLORE_OWN_MESSAGE_FIELDS = (
506
+ /* GraphQL */
507
+ `
508
+ ${EXPLORE_MESSAGE_FIELDS}
509
+ feedback {
510
+ rating
511
+ reason
512
+ comment
513
+ createdAt
514
+ }
515
+ `
516
+ );
517
+ var EXPLORE_CATALOG_QUERY = (
518
+ /* GraphQL */
519
+ `
520
+ query ExploreCatalog($productSlug: String) {
521
+ exploreCatalog(productSlug: $productSlug) {
522
+ enabled
523
+ products {
524
+ slug
525
+ name
526
+ tagline
527
+ website
528
+ }
529
+ examplePrompts
530
+ welcomeTitle
531
+ welcomeBody
532
+ limits {
533
+ maxMessageLength
534
+ maxTurnsPerConversation
535
+ messagesPerDay
536
+ historyTurns
537
+ }
538
+ captchaRequired
539
+ recaptchaSiteKey
540
+ }
541
+ }
542
+ `
543
+ );
544
+ var EXPLORE_MESSAGE_QUERY = (
545
+ /* GraphQL */
546
+ `
547
+ query ExploreMessage($conversationToken: String!, $id: ID!) {
548
+ exploreMessage(conversationToken: $conversationToken, id: $id) {
549
+ ${EXPLORE_OWN_MESSAGE_FIELDS}
550
+ }
551
+ }
552
+ `
553
+ );
554
+ var SEND_EXPLORE_MESSAGE_MUTATION = (
555
+ /* GraphQL */
556
+ `
557
+ mutation SendExploreMessage($input: SendExploreMessageInput!) {
558
+ sendExploreMessage(input: $input) {
559
+ conversation {
560
+ id
561
+ token
562
+ productSlug
563
+ turnCount
564
+ createdAt
565
+ }
566
+ userMessage {
567
+ ${EXPLORE_OWN_MESSAGE_FIELDS}
568
+ }
569
+ assistantMessage {
570
+ ${EXPLORE_OWN_MESSAGE_FIELDS}
571
+ }
572
+ remainingToday
573
+ }
574
+ }
575
+ `
576
+ );
577
+ var RECORD_EXPLORE_CLICK_MUTATION = (
578
+ /* GraphQL */
579
+ `
580
+ mutation RecordExploreClick($input: RecordExploreClickInput!) {
581
+ recordExploreClick(input: $input) {
582
+ recorded
583
+ }
584
+ }
585
+ `
586
+ );
587
+ var SUBMIT_EXPLORE_FEEDBACK_MUTATION = (
588
+ /* GraphQL */
589
+ `
590
+ mutation SubmitExploreFeedback($input: SubmitExploreFeedbackInput!) {
591
+ submitExploreFeedback(input: $input) {
592
+ recorded
593
+ feedback {
594
+ rating
595
+ reason
596
+ comment
597
+ createdAt
598
+ }
599
+ }
600
+ }
601
+ `
602
+ );
603
+ var EXPLORE_FEEDBACK_COMMENT_SOFT_MAX = 500;
604
+ var CREATE_EXPLORE_SHARE_LINK_MUTATION = (
605
+ /* GraphQL */
606
+ `
607
+ mutation CreateExploreShareLink($conversationToken: String!) {
608
+ createExploreShareLink(conversationToken: $conversationToken) {
609
+ shareToken
610
+ }
611
+ }
612
+ `
613
+ );
614
+ var EXPLORE_SHARED_CONVERSATION_QUERY = (
615
+ /* GraphQL */
616
+ `
617
+ query ExploreSharedConversation($shareToken: String!) {
618
+ exploreSharedConversation(shareToken: $shareToken) {
619
+ ${EXPLORE_MESSAGE_FIELDS}
620
+ }
621
+ }
622
+ `
623
+ );
354
624
  function MarkdownLink({
355
625
  href,
356
626
  children,
@@ -790,135 +1060,6 @@ function useWebSDK() {
790
1060
  return client;
791
1061
  }
792
1062
 
793
- // src/components/explore-types.ts
794
- var EXPLORE_MESSAGE_FIELDS = (
795
- /* GraphQL */
796
- `
797
- id
798
- conversationId
799
- role
800
- status
801
- content
802
- partialContent
803
- activity
804
- references {
805
- url
806
- title
807
- description
808
- product
809
- imageUrl
810
- index
811
- }
812
- ctas {
813
- kind
814
- label
815
- url
816
- product
817
- }
818
- followUps
819
- answered
820
- attachments {
821
- name
822
- mimeType
823
- size
824
- textExtracted
825
- }
826
- errorCode
827
- createdAt
828
- completedAt
829
- `
830
- );
831
- var EXPLORE_CATALOG_QUERY = (
832
- /* GraphQL */
833
- `
834
- query ExploreCatalog($productSlug: String) {
835
- exploreCatalog(productSlug: $productSlug) {
836
- enabled
837
- products {
838
- slug
839
- name
840
- tagline
841
- website
842
- }
843
- examplePrompts
844
- welcomeTitle
845
- welcomeBody
846
- limits {
847
- maxMessageLength
848
- maxTurnsPerConversation
849
- messagesPerDay
850
- historyTurns
851
- }
852
- captchaRequired
853
- recaptchaSiteKey
854
- }
855
- }
856
- `
857
- );
858
- var EXPLORE_MESSAGE_QUERY = (
859
- /* GraphQL */
860
- `
861
- query ExploreMessage($conversationToken: String!, $id: ID!) {
862
- exploreMessage(conversationToken: $conversationToken, id: $id) {
863
- ${EXPLORE_MESSAGE_FIELDS}
864
- }
865
- }
866
- `
867
- );
868
- var SEND_EXPLORE_MESSAGE_MUTATION = (
869
- /* GraphQL */
870
- `
871
- mutation SendExploreMessage($input: SendExploreMessageInput!) {
872
- sendExploreMessage(input: $input) {
873
- conversation {
874
- id
875
- token
876
- productSlug
877
- turnCount
878
- createdAt
879
- }
880
- userMessage {
881
- ${EXPLORE_MESSAGE_FIELDS}
882
- }
883
- assistantMessage {
884
- ${EXPLORE_MESSAGE_FIELDS}
885
- }
886
- remainingToday
887
- }
888
- }
889
- `
890
- );
891
- var RECORD_EXPLORE_CLICK_MUTATION = (
892
- /* GraphQL */
893
- `
894
- mutation RecordExploreClick($input: RecordExploreClickInput!) {
895
- recordExploreClick(input: $input) {
896
- recorded
897
- }
898
- }
899
- `
900
- );
901
- var CREATE_EXPLORE_SHARE_LINK_MUTATION = (
902
- /* GraphQL */
903
- `
904
- mutation CreateExploreShareLink($conversationToken: String!) {
905
- createExploreShareLink(conversationToken: $conversationToken) {
906
- shareToken
907
- }
908
- }
909
- `
910
- );
911
- var EXPLORE_SHARED_CONVERSATION_QUERY = (
912
- /* GraphQL */
913
- `
914
- query ExploreSharedConversation($shareToken: String!) {
915
- exploreSharedConversation(shareToken: $shareToken) {
916
- ${EXPLORE_MESSAGE_FIELDS}
917
- }
918
- }
919
- `
920
- );
921
-
922
1063
  // src/data/products.ts
923
1064
  var ECOSYSTEM_PRODUCTS = [
924
1065
  {
@@ -1946,6 +2087,42 @@ function useExploreChat(options = {}) {
1946
2087
  },
1947
2088
  [client]
1948
2089
  );
2090
+ const submitFeedback = useCallback(
2091
+ async (messageId, rating, detail) => {
2092
+ const token = conversationTokenRef.current;
2093
+ if (!token) return false;
2094
+ const comment = detail?.comment?.trim();
2095
+ const input = {
2096
+ conversationToken: token,
2097
+ messageId,
2098
+ rating,
2099
+ // Only meaningful with NOT_HELPFUL. The server stores null for HELPFUL either
2100
+ // way; sending it would just be noise the backend has to defend against.
2101
+ reason: rating === "NOT_HELPFUL" ? detail?.reason ?? null : null,
2102
+ comment: comment ? comment : null
2103
+ };
2104
+ try {
2105
+ const res = await client.mutate(
2106
+ SUBMIT_EXPLORE_FEEDBACK_MUTATION,
2107
+ { input }
2108
+ );
2109
+ const result = res?.data?.submitExploreFeedback;
2110
+ if (!result?.recorded) return false;
2111
+ const recorded = result.feedback;
2112
+ if (recorded && mountedRef.current) {
2113
+ setMessages(
2114
+ (current) => current.map(
2115
+ (message) => message.id === messageId ? { ...message, feedback: recorded } : message
2116
+ )
2117
+ );
2118
+ }
2119
+ return true;
2120
+ } catch {
2121
+ return false;
2122
+ }
2123
+ },
2124
+ [client]
2125
+ );
1949
2126
  return {
1950
2127
  phase,
1951
2128
  catalog,
@@ -1965,6 +2142,7 @@ function useExploreChat(options = {}) {
1965
2142
  deleteConversation,
1966
2143
  clearHistory,
1967
2144
  recordClick,
2145
+ submitFeedback,
1968
2146
  createShareLink,
1969
2147
  isSharedView
1970
2148
  };
@@ -3020,6 +3198,206 @@ function ThinkingIndicator({ activity }) {
3020
3198
  }
3021
3199
  );
3022
3200
  }
3201
+ function AnswerFeedback({
3202
+ strings: T,
3203
+ messageId,
3204
+ feedback,
3205
+ onSubmit
3206
+ }) {
3207
+ const [local, setLocal] = useState(null);
3208
+ const [failed, setFailed] = useState(false);
3209
+ const [sending, setSending] = useState(false);
3210
+ const [chooserOpen, setChooserOpen] = useState(false);
3211
+ const [reason, setReason] = useState(null);
3212
+ const [comment, setComment] = useState("");
3213
+ const downRef = useRef(null);
3214
+ const firstReasonRef = useRef(null);
3215
+ const inFlightRef = useRef(false);
3216
+ const panelId = `boff-explore-feedback-${messageId}`;
3217
+ const rating = local ?? feedback?.rating ?? null;
3218
+ const rated = rating !== null;
3219
+ const reasonLabels = {
3220
+ INACCURATE: T.feedbackReasonInaccurate,
3221
+ INCOMPLETE: T.feedbackReasonIncomplete,
3222
+ OFF_TOPIC: T.feedbackReasonOffTopic,
3223
+ HARD_TO_FOLLOW: T.feedbackReasonHardToFollow,
3224
+ OTHER: T.feedbackReasonOther
3225
+ };
3226
+ const closeChooser = useCallback(() => {
3227
+ setChooserOpen(false);
3228
+ downRef.current?.focus();
3229
+ }, []);
3230
+ const submit = useCallback(
3231
+ async (next, detail) => {
3232
+ if (inFlightRef.current) return;
3233
+ inFlightRef.current = true;
3234
+ setSending(true);
3235
+ setFailed(false);
3236
+ setLocal(next);
3237
+ const recorded = await onSubmit(next, detail);
3238
+ inFlightRef.current = false;
3239
+ setSending(false);
3240
+ if (recorded) return;
3241
+ setLocal(null);
3242
+ setFailed(true);
3243
+ },
3244
+ [onSubmit]
3245
+ );
3246
+ const onThumbUp = useCallback(() => {
3247
+ setChooserOpen(false);
3248
+ void submit("HELPFUL");
3249
+ }, [submit]);
3250
+ const onThumbDown = useCallback(() => {
3251
+ setChooserOpen((open) => !open);
3252
+ }, []);
3253
+ const onSendReason = useCallback(() => {
3254
+ setChooserOpen(false);
3255
+ void submit("NOT_HELPFUL", { reason, comment });
3256
+ }, [comment, reason, submit]);
3257
+ useEffect(() => {
3258
+ if (!chooserOpen) return;
3259
+ firstReasonRef.current?.focus();
3260
+ }, [chooserOpen]);
3261
+ const thumbClass = (active) => cn(
3262
+ "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full border transition-colors",
3263
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
3264
+ "disabled:pointer-events-none disabled:opacity-50",
3265
+ active ? "border-primary/40 bg-accent text-primary" : "border-border bg-card text-muted-foreground hover:border-primary/40 hover:bg-accent hover:text-foreground"
3266
+ );
3267
+ return /* @__PURE__ */ jsxs(
3268
+ "div",
3269
+ {
3270
+ "data-boff-explore": "feedback",
3271
+ "data-rating": rating ?? "none",
3272
+ className: "pt-0.5",
3273
+ children: [
3274
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
3275
+ /* @__PURE__ */ jsx(
3276
+ "p",
3277
+ {
3278
+ "data-boff-explore": "feedback-status",
3279
+ role: "status",
3280
+ className: "text-xs text-muted-foreground",
3281
+ children: failed ? T.feedbackNotSent : rated ? T.feedbackThanks : T.feedbackPrompt
3282
+ }
3283
+ ),
3284
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
3285
+ /* @__PURE__ */ jsx(
3286
+ "button",
3287
+ {
3288
+ "data-boff-explore": "feedback-up",
3289
+ type: "button",
3290
+ disabled: sending,
3291
+ "aria-label": T.feedbackHelpful,
3292
+ title: T.feedbackHelpful,
3293
+ "aria-pressed": rating === "HELPFUL",
3294
+ onClick: onThumbUp,
3295
+ className: thumbClass(rating === "HELPFUL"),
3296
+ children: /* @__PURE__ */ jsx(ThumbsUp, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
3297
+ }
3298
+ ),
3299
+ /* @__PURE__ */ jsx(
3300
+ "button",
3301
+ {
3302
+ ref: downRef,
3303
+ "data-boff-explore": "feedback-down",
3304
+ type: "button",
3305
+ disabled: sending,
3306
+ "aria-label": T.feedbackNotHelpful,
3307
+ title: T.feedbackNotHelpful,
3308
+ "aria-pressed": rating === "NOT_HELPFUL",
3309
+ "aria-expanded": chooserOpen,
3310
+ "aria-controls": chooserOpen ? panelId : void 0,
3311
+ onClick: onThumbDown,
3312
+ className: thumbClass(rating === "NOT_HELPFUL" || chooserOpen),
3313
+ children: /* @__PURE__ */ jsx(ThumbsDown, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
3314
+ }
3315
+ )
3316
+ ] })
3317
+ ] }),
3318
+ chooserOpen ? /* @__PURE__ */ jsxs(
3319
+ "div",
3320
+ {
3321
+ id: panelId,
3322
+ "data-boff-explore": "feedback-reasons",
3323
+ role: "group",
3324
+ "aria-label": T.feedbackReasonTitle,
3325
+ onKeyDown: (event) => {
3326
+ if (event.key !== "Escape") return;
3327
+ event.stopPropagation();
3328
+ closeChooser();
3329
+ },
3330
+ className: "boff-explore-fade mt-2 rounded-xl border border-border bg-card p-3",
3331
+ children: [
3332
+ /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium text-card-foreground", children: T.feedbackReasonTitle }),
3333
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: EXPLORE_FEEDBACK_REASONS.map((code, index) => /* @__PURE__ */ jsx(
3334
+ "button",
3335
+ {
3336
+ ref: index === 0 ? firstReasonRef : void 0,
3337
+ "data-boff-explore": "feedback-reason",
3338
+ "data-reason": code,
3339
+ type: "button",
3340
+ "aria-pressed": reason === code,
3341
+ onClick: () => setReason((current) => current === code ? null : code),
3342
+ className: cn(
3343
+ "inline-flex max-w-full items-center rounded-full border px-3 py-1 text-xs transition-colors",
3344
+ "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
3345
+ reason === code ? "border-primary/40 bg-accent text-primary" : "border-border bg-background text-muted-foreground hover:border-primary/40 hover:bg-accent hover:text-foreground"
3346
+ ),
3347
+ children: /* @__PURE__ */ jsx("span", { className: "truncate", children: reasonLabels[code] })
3348
+ },
3349
+ code
3350
+ )) }),
3351
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [
3352
+ /* @__PURE__ */ jsx(
3353
+ "input",
3354
+ {
3355
+ "data-boff-explore": "feedback-comment",
3356
+ type: "text",
3357
+ value: comment,
3358
+ onChange: (event) => setComment(event.target.value),
3359
+ onKeyDown: (event) => {
3360
+ if (event.key !== "Enter") return;
3361
+ event.preventDefault();
3362
+ onSendReason();
3363
+ },
3364
+ "aria-label": T.feedbackCommentPlaceholder,
3365
+ placeholder: T.feedbackCommentPlaceholder,
3366
+ maxLength: EXPLORE_FEEDBACK_COMMENT_SOFT_MAX,
3367
+ className: "min-w-0 flex-1 rounded-md border border-border bg-background px-2 py-1 text-base text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:text-sm"
3368
+ }
3369
+ ),
3370
+ /* @__PURE__ */ jsx(
3371
+ Button,
3372
+ {
3373
+ "data-boff-explore": "feedback-send",
3374
+ type: "button",
3375
+ size: "sm",
3376
+ disabled: sending,
3377
+ onClick: onSendReason,
3378
+ children: T.feedbackSend
3379
+ }
3380
+ ),
3381
+ /* @__PURE__ */ jsx(
3382
+ Button,
3383
+ {
3384
+ "data-boff-explore": "feedback-dismiss",
3385
+ type: "button",
3386
+ size: "sm",
3387
+ variant: "ghost",
3388
+ className: "text-muted-foreground",
3389
+ onClick: closeChooser,
3390
+ children: T.feedbackDismiss
3391
+ }
3392
+ )
3393
+ ] })
3394
+ ]
3395
+ }
3396
+ ) : null
3397
+ ]
3398
+ }
3399
+ );
3400
+ }
3023
3401
  function UserBubble({
3024
3402
  strings: T,
3025
3403
  message
@@ -3068,7 +3446,8 @@ function AssistantBubble({
3068
3446
  onNavigate,
3069
3447
  anchorRef,
3070
3448
  onFollow,
3071
- onFollowUp
3449
+ onFollowUp,
3450
+ onFeedback
3072
3451
  }) {
3073
3452
  const streaming = message.status === "PENDING" || message.status === "RUNNING";
3074
3453
  const body = message.content || message.partialContent || "";
@@ -3179,7 +3558,16 @@ function AssistantBubble({
3179
3558
  },
3180
3559
  question
3181
3560
  )) })
3182
- ] }) : null
3561
+ ] }) : null,
3562
+ completed && onFeedback ? /* @__PURE__ */ jsx(
3563
+ AnswerFeedback,
3564
+ {
3565
+ strings: T,
3566
+ messageId: message.id,
3567
+ feedback: message.feedback,
3568
+ onSubmit: onFeedback
3569
+ }
3570
+ ) : null
3183
3571
  ] })
3184
3572
  ]
3185
3573
  }
@@ -3583,6 +3971,7 @@ function ExplorePage({
3583
3971
  deleteConversation,
3584
3972
  clearHistory,
3585
3973
  recordClick,
3974
+ submitFeedback,
3586
3975
  createShareLink,
3587
3976
  isSharedView
3588
3977
  } = useExploreChat({
@@ -3639,6 +4028,10 @@ function ExplorePage({
3639
4028
  () => catalog.products.find((p) => p.slug === focusProduct)?.name ?? null,
3640
4029
  [catalog.products, focusProduct]
3641
4030
  );
4031
+ const headProductName = useMemo(
4032
+ () => productSlug ? catalog.products.find((p) => p.slug === productSlug)?.name ?? null : null,
4033
+ [catalog.products, productSlug]
4034
+ );
3642
4035
  const imageOrigins = useMemo(
3643
4036
  () => inlineImageOrigins(catalog.products),
3644
4037
  [catalog.products]
@@ -4003,16 +4396,17 @@ function ExplorePage({
4003
4396
  ),
4004
4397
  style: rootStyle,
4005
4398
  children: [
4006
- seo ? /* @__PURE__ */ jsx(
4399
+ /* @__PURE__ */ jsx(
4007
4400
  PageHead,
4008
4401
  {
4009
- title: seo.title ?? "Explore \u2014 ask anything about our products",
4010
- description: seo.description ?? "Ask questions in plain English and get answers drawn from our product documentation, with links to the exact pages they came from.",
4011
- keywords: seo.keywords,
4012
- image: seo.image,
4013
- url: seo.url
4402
+ title: seo?.title ?? T.seoTitle,
4403
+ description: seo?.description ?? (headProductName ? fill(T.seoDescriptionProduct, { product: headProductName }) : T.seoDescription),
4404
+ productName: seo?.title ? void 0 : headProductName ?? void 0,
4405
+ keywords: seo?.keywords,
4406
+ image: seo?.image,
4407
+ url: seo?.url
4014
4408
  }
4015
- ) : null,
4409
+ ),
4016
4410
  /* @__PURE__ */ jsx(ProseStyles, {}),
4017
4411
  /* @__PURE__ */ jsx(ExploreStyles, {}),
4018
4412
  !showWelcome ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 border-b border-border px-4 py-2.5", children: [
@@ -4189,7 +4583,8 @@ function ExplorePage({
4189
4583
  onNavigate,
4190
4584
  anchorRef: message.id === latestAssistantId ? latestAssistantRef : void 0,
4191
4585
  onFollow: (kind, url) => recordClick(message.id, kind, url),
4192
- onFollowUp: sendPrompt
4586
+ onFollowUp: sendPrompt,
4587
+ onFeedback: isSharedView ? void 0 : (rating, detail) => submitFeedback(message.id, rating, detail)
4193
4588
  },
4194
4589
  message.id
4195
4590
  )