@helpai/elements 0.58.1 → 0.59.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/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-BAOjO2dQ.js';
1
+ export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-Daefe1g1.js';
2
2
  import 'zod';
3
3
 
4
4
  /**
@@ -40,7 +40,7 @@ interface ClientStorage {
40
40
  * populated {@link Strings} map. UI components then read `strings.send` as a
41
41
  * normal property access — no per-render lookup, no per-render allocation.
42
42
  */
43
- type StringKey = "launcherOpen" | "launcherLabel" | "panelTitle" | "composerPlaceholder" | "send" | "stop" | "attach" | "micStart" | "micStop" | "micUnsupported" | "expand" | "collapse" | "fullscreen" | "exitFullscreen" | "resizeHandle" | "scrollToBottom" | "close" | "moreActions" | "soundOn" | "soundOff" | "language" | "theme" | "themeAuto" | "themeLight" | "themeDark" | "textSize" | "textSizeSmall" | "textSizeNormal" | "textSizeLarge" | "history" | "historyTitle" | "historyEmpty" | "historyLoading" | "historyBack" | "historyContinue" | "conversationLoading" | "conversationClosed" | "startNewConversation" | "dateToday" | "dateYesterday" | "dateLastWeek" | "dateOlder" | "newConversation" | "dropZone" | "attachmentTooLarge" | "attachmentTooMany" | "attachmentMimeRejected" | "errorRetry" | "errorGeneric" | "errorRateLimited" | "loading" | "thinking" | "thoughts" | "usedTool" | "toolResult" | "sources" | "feedbackUp" | "feedbackDown" | "feedbackThanks" | "copy" | "copied" | "collapseSidebar" | "expandSidebar" | "formSubmit" | "formSkip" | "formSubmitted" | "formSkipped" | "formFillOut" | "formRequired" | "formInvalidEmail" | "formInvalidTel" | "formInvalidUrl" | "formInvalidNumber" | "formTooShort" | "formTooLong" | "formNumberTooSmall" | "formNumberTooLarge" | "formPatternMismatch" | "formChooseAtLeast" | "formChooseAtMost" | "formOther" | "formOtherPlaceholder" | "inputRequired" | "inputBadge" | "inputAnswered" | "inputSkipped" | "inputSubmit" | "inputSubmitHint" | "inputSkip" | "showOptions" | "hideOptions" | "qtypeText" | "qtypeEmail" | "qtypePhone" | "qtypeNumber" | "qtypeDate" | "qtypeChooseOne" | "qtypeChooseAny" | "qtypeBoolean" | "confirmYes" | "confirmNo" | "approvalRequired" | "approve" | "reject" | "approved" | "rejected" | "approvalReason" | "approvalPrompt" | "approvalBody" | "approvalYourResponse" | "approvalEditHint" | "approvalSubmitting" | "edit" | "toolParameters" | "statusAwaiting" | "statusResponded" | "statusCompleted" | "statusDenied" | "statusError" | "statusRunning" | "statusSuperseded" | "tabHome" | "tabConversations" | "tabHelp" | "tabNews" | "modulesEmpty" | "moduleBack" | "contentLoading" | "homeGreeting" | "homeGreetingNamed" | "homeGreetingLead" | "homeSearchPlaceholder" | "homeContentTitle" | "homeStatus" | "helpTitle" | "helpSearchPlaceholder" | "helpEmpty" | "helpLoading" | "helpSearchEmpty" | "newsTitle" | "newsEmpty" | "newsLoading" | "newsBack" | "newsPublishedAt";
43
+ type StringKey = "launcherOpen" | "launcherLabel" | "panelTitle" | "composerPlaceholder" | "send" | "stop" | "attach" | "micStart" | "micStop" | "micUnsupported" | "expand" | "collapse" | "fullscreen" | "exitFullscreen" | "resizeHandle" | "scrollToBottom" | "close" | "moreActions" | "soundOn" | "soundOff" | "language" | "theme" | "themeAuto" | "themeLight" | "themeDark" | "textSize" | "textSizeSmall" | "textSizeNormal" | "textSizeLarge" | "history" | "historyTitle" | "historyEmpty" | "historyLoading" | "historyBack" | "historyContinue" | "conversationLoading" | "conversationClosed" | "startNewConversation" | "dateToday" | "dateYesterday" | "dateLastWeek" | "dateOlder" | "newConversation" | "dropZone" | "attachmentTooLarge" | "attachmentTooMany" | "attachmentMimeRejected" | "errorRetry" | "errorGeneric" | "errorRateLimited" | "loading" | "thinking" | "thoughts" | "toolResult" | "sources" | "feedbackUp" | "feedbackDown" | "feedbackThanks" | "copy" | "copied" | "collapseSidebar" | "expandSidebar" | "formSubmit" | "formSkip" | "formSubmitted" | "formSkipped" | "formFillOut" | "formRequired" | "formInvalidEmail" | "formInvalidTel" | "formInvalidUrl" | "formInvalidNumber" | "formTooShort" | "formTooLong" | "formNumberTooSmall" | "formNumberTooLarge" | "formPatternMismatch" | "formChooseAtLeast" | "formChooseAtMost" | "formOther" | "formOtherPlaceholder" | "inputRequired" | "inputBadge" | "inputAnswered" | "inputSkipped" | "inputSubmit" | "inputSubmitHint" | "inputSkip" | "showOptions" | "hideOptions" | "qtypeText" | "qtypeEmail" | "qtypePhone" | "qtypeNumber" | "qtypeDate" | "qtypeChooseOne" | "qtypeChooseAny" | "qtypeBoolean" | "confirmYes" | "confirmNo" | "approve" | "reject" | "approvalPrompt" | "approvalBody" | "approvalYourResponse" | "approvalEditHint" | "approvalSubmitting" | "edit" | "toolParameters" | "statusAwaiting" | "statusResponded" | "statusCompleted" | "statusDenied" | "statusError" | "statusRunning" | "statusSuperseded" | "tabHome" | "tabConversations" | "tabHelp" | "tabNews" | "modulesEmpty" | "moduleBack" | "contentLoading" | "homeGreeting" | "homeGreetingNamed" | "homeGreetingLead" | "homeSearchPlaceholder" | "homeContentTitle" | "homeStatus" | "helpTitle" | "helpSearchPlaceholder" | "helpEmpty" | "helpLoading" | "helpSearchEmpty" | "newsTitle" | "newsEmpty" | "newsLoading" | "newsBack" | "newsPublishedAt";
44
44
  /** A partial map for one locale — what overrides look like on the wire. */
45
45
  type LocaleStrings = Partial<Record<StringKey, string>>;
46
46
  /**
package/index.mjs CHANGED
@@ -29,7 +29,7 @@ var BRAND = {
29
29
  };
30
30
 
31
31
  // src/core/version.ts
32
- var ELEMENTS_VERSION = true ? "0.58.1" : "0.0.0-dev";
32
+ var ELEMENTS_VERSION = true ? "0.59.0" : "0.0.0-dev";
33
33
  var ELEMENTS_VERSION_PARAM = "_ev";
34
34
 
35
35
  // src/i18n/strings.ts
@@ -89,7 +89,6 @@ var STRINGS_EN = {
89
89
  loading: "Loading\u2026",
90
90
  thinking: "Thinking\u2026",
91
91
  thoughts: "Thoughts",
92
- usedTool: "Used tool",
93
92
  toolResult: "Result",
94
93
  sources: "Sources",
95
94
  feedbackUp: "Good response",
@@ -160,12 +159,8 @@ var STRINGS_EN = {
160
159
  inputSkip: "Skip",
161
160
  confirmYes: "Yes",
162
161
  confirmNo: "No",
163
- approvalRequired: "Approval required",
164
162
  approve: "Approve",
165
163
  reject: "Reject",
166
- approved: "Approved",
167
- rejected: "Rejected",
168
- approvalReason: "Add a reason (optional)",
169
164
  approvalPrompt: "{tool} requires your approval to execute.",
170
165
  approvalBody: "Review the tool input above and decide whether to allow this action.",
171
166
  approvalYourResponse: "Your response: {decision}",
@@ -237,7 +232,6 @@ var STRINGS_FR = {
237
232
  loading: "Chargement\u2026",
238
233
  thinking: "R\xE9flexion\u2026",
239
234
  thoughts: "R\xE9flexions",
240
- usedTool: "Outil utilis\xE9",
241
235
  toolResult: "R\xE9sultat",
242
236
  sources: "Sources",
243
237
  feedbackUp: "Bonne r\xE9ponse",
@@ -308,12 +302,8 @@ var STRINGS_FR = {
308
302
  inputSkip: "Ignorer",
309
303
  confirmYes: "Oui",
310
304
  confirmNo: "Non",
311
- approvalRequired: "Approbation requise",
312
305
  approve: "Approuver",
313
306
  reject: "Refuser",
314
- approved: "Approuv\xE9",
315
- rejected: "Refus\xE9",
316
- approvalReason: "Ajouter une raison (facultatif)",
317
307
  approvalPrompt: "{tool} n\xE9cessite votre approbation pour s'ex\xE9cuter.",
318
308
  approvalBody: "V\xE9rifiez les param\xE8tres ci-dessus et d\xE9cidez d'autoriser ou non cette action.",
319
309
  approvalYourResponse: "Votre r\xE9ponse : {decision}",
@@ -385,7 +375,6 @@ var STRINGS_AR = {
385
375
  loading: "\u062C\u0627\u0631\u064D \u0627\u0644\u062A\u062D\u0645\u064A\u0644\u2026",
386
376
  thinking: "\u064A\u0641\u0643\u0651\u0631\u2026",
387
377
  thoughts: "\u0627\u0644\u0623\u0641\u0643\u0627\u0631",
388
- usedTool: "\u0623\u062F\u0627\u0629 \u0645\u064F\u0633\u062A\u062E\u062F\u064E\u0645\u0629",
389
378
  toolResult: "\u0627\u0644\u0646\u062A\u064A\u062C\u0629",
390
379
  sources: "\u0627\u0644\u0645\u0635\u0627\u062F\u0631",
391
380
  feedbackUp: "\u0631\u062F \u062C\u064A\u062F",
@@ -456,12 +445,8 @@ var STRINGS_AR = {
456
445
  inputSkip: "\u062A\u062E\u0637\u064D\u0651",
457
446
  confirmYes: "\u0646\u0639\u0645",
458
447
  confirmNo: "\u0644\u0627",
459
- approvalRequired: "\u0645\u0637\u0644\u0648\u0628 \u0645\u0648\u0627\u0641\u0642\u0629",
460
448
  approve: "\u0645\u0648\u0627\u0641\u0642\u0629",
461
449
  reject: "\u0631\u0641\u0636",
462
- approved: "\u062A\u0645\u062A \u0627\u0644\u0645\u0648\u0627\u0641\u0642\u0629",
463
- rejected: "\u0645\u0631\u0641\u0648\u0636",
464
- approvalReason: "\u0623\u0636\u0641 \u0633\u0628\u0628\u064B\u0627 (\u0627\u062E\u062A\u064A\u0627\u0631\u064A)",
465
450
  approvalPrompt: "\u062A\u062A\u0637\u0644\u0628 {tool} \u0645\u0648\u0627\u0641\u0642\u062A\u0643 \u0644\u0644\u062A\u0646\u0641\u064A\u0630.",
466
451
  approvalBody: "\u0631\u0627\u062C\u0639 \u0645\u064F\u0639\u0637\u064A\u0627\u062A \u0627\u0644\u0623\u062F\u0627\u0629 \u0623\u0639\u0644\u0627\u0647 \u0648\u0642\u0631\u0651\u0631 \u0627\u0644\u0633\u0645\u0627\u062D \u0628\u0647\u0630\u0627 \u0627\u0644\u0625\u062C\u0631\u0627\u0621 \u0623\u0648 \u0631\u0641\u0636\u0647.",
467
452
  approvalYourResponse: "\u0631\u062F\u0651\u0643: {decision}",
@@ -533,7 +518,6 @@ var STRINGS_ES = {
533
518
  loading: "Cargando\u2026",
534
519
  thinking: "Pensando\u2026",
535
520
  thoughts: "Razonamiento",
536
- usedTool: "Herramienta usada",
537
521
  toolResult: "Resultado",
538
522
  sources: "Fuentes",
539
523
  feedbackUp: "Buena respuesta",
@@ -604,12 +588,8 @@ var STRINGS_ES = {
604
588
  inputSkip: "Omitir",
605
589
  confirmYes: "S\xED",
606
590
  confirmNo: "No",
607
- approvalRequired: "Aprobaci\xF3n requerida",
608
591
  approve: "Aprobar",
609
592
  reject: "Rechazar",
610
- approved: "Aprobado",
611
- rejected: "Rechazado",
612
- approvalReason: "A\xF1ade un motivo (opcional)",
613
593
  approvalPrompt: "{tool} requiere tu aprobaci\xF3n para ejecutarse.",
614
594
  approvalBody: "Revisa los par\xE1metros de arriba y decide si permites esta acci\xF3n.",
615
595
  approvalYourResponse: "Tu respuesta: {decision}",
@@ -681,7 +661,6 @@ var STRINGS_HE = {
681
661
  loading: "\u05D8\u05D5\u05E2\u05DF\u2026",
682
662
  thinking: "\u05D7\u05D5\u05E9\u05D1\u2026",
683
663
  thoughts: "\u05DE\u05D7\u05E9\u05D1\u05D5\u05EA",
684
- usedTool: "\u05DB\u05DC\u05D9 \u05D1\u05E9\u05D9\u05DE\u05D5\u05E9",
685
664
  toolResult: "\u05EA\u05D5\u05E6\u05D0\u05D4",
686
665
  sources: "\u05DE\u05E7\u05D5\u05E8\u05D5\u05EA",
687
666
  feedbackUp: "\u05EA\u05E9\u05D5\u05D1\u05D4 \u05D8\u05D5\u05D1\u05D4",
@@ -752,12 +731,8 @@ var STRINGS_HE = {
752
731
  inputSkip: "\u05D3\u05D9\u05DC\u05D5\u05D2",
753
732
  confirmYes: "\u05DB\u05DF",
754
733
  confirmNo: "\u05DC\u05D0",
755
- approvalRequired: "\u05E0\u05D3\u05E8\u05E9 \u05D0\u05D9\u05E9\u05D5\u05E8",
756
734
  approve: "\u05D0\u05D9\u05E9\u05D5\u05E8",
757
735
  reject: "\u05D3\u05D7\u05D9\u05D9\u05D4",
758
- approved: "\u05D0\u05D5\u05E9\u05E8",
759
- rejected: "\u05E0\u05D3\u05D7\u05D4",
760
- approvalReason: "\u05D4\u05D5\u05E1\u05E3 \u05E1\u05D9\u05D1\u05D4 (\u05D0\u05D5\u05E4\u05E6\u05D9\u05D5\u05E0\u05DC\u05D9)",
761
736
  approvalPrompt: "\u05D4\u05DB\u05DC\u05D9 {tool} \u05D3\u05D5\u05E8\u05E9 \u05D0\u05EA \u05D0\u05D9\u05E9\u05D5\u05E8\u05DA \u05DB\u05D3\u05D9 \u05DC\u05E4\u05E2\u05D5\u05DC.",
762
737
  approvalBody: "\u05D1\u05D3\u05D5\u05E7 \u05D0\u05EA \u05E4\u05E8\u05DE\u05D8\u05E8\u05D9 \u05D4\u05DB\u05DC\u05D9 \u05E9\u05DC\u05DE\u05E2\u05DC\u05D4 \u05D5\u05D4\u05D7\u05DC\u05D8 \u05D0\u05DD \u05DC\u05D0\u05E9\u05E8 \u05E4\u05E2\u05D5\u05DC\u05D4 \u05D6\u05D5.",
763
738
  approvalYourResponse: "\u05D4\u05EA\u05D2\u05D5\u05D1\u05D4 \u05E9\u05DC\u05DA: {decision}",
@@ -3233,6 +3208,8 @@ var StreamReducer = class {
3233
3208
  return;
3234
3209
  case "data-conversation-rebind":
3235
3210
  return;
3211
+ case "data-suggestions":
3212
+ return;
3236
3213
  default: {
3237
3214
  const _exhaustive = chunk;
3238
3215
  void _exhaustive;
@@ -5653,6 +5630,12 @@ function toolDecisionState(state, approval) {
5653
5630
  const responded = state === "approval-responded" || approval?.approved !== void 0;
5654
5631
  return { terminal, responded, decided: terminal || responded };
5655
5632
  }
5633
+ function StatusPill({ status, icon, label }) {
5634
+ return /* @__PURE__ */ jsxs12("span", { class: `${p14}-toolui-badge ${p14}-toolui-status`, "data-status": status, children: [
5635
+ /* @__PURE__ */ jsx15("span", { class: `${p14}-toolui-status-icon`, children: icon }),
5636
+ label
5637
+ ] });
5638
+ }
5656
5639
  function statusOf(state, approval) {
5657
5640
  if (state === "output-error") return "error";
5658
5641
  if (state === "output-denied" || approval?.approved === false) return "denied";
@@ -5692,10 +5675,7 @@ function ToolStatus({
5692
5675
  }) {
5693
5676
  const base = statusOf(state, approval);
5694
5677
  const status = superseded && (base === "awaiting" || base === "running") ? "superseded" : base;
5695
- return /* @__PURE__ */ jsxs12("span", { class: `${p14}-toolui-badge ${p14}-toolui-status`, "data-status": status, children: [
5696
- /* @__PURE__ */ jsx15("span", { class: `${p14}-toolui-status-icon`, children: /* @__PURE__ */ jsx15(StatusIcon, { status }) }),
5697
- statusLabel(status, strings)
5698
- ] });
5678
+ return /* @__PURE__ */ jsx15(StatusPill, { status, icon: /* @__PURE__ */ jsx15(StatusIcon, { status }), label: statusLabel(status, strings) });
5699
5679
  }
5700
5680
  function ToolHeaderRow({
5701
5681
  name,
@@ -5920,18 +5900,18 @@ function ToolAskQuestions({ part, strings, active, superseded = false, onDecisio
5920
5900
  const req = useComputed4(() => parseAskUserQuestions(part.inputSig.value)).value;
5921
5901
  const { terminal, decided } = toolDecisionState(state, approval);
5922
5902
  const answered = decided && approval?.approved === true;
5923
- const editable = !decided && !superseded;
5924
- const skipped = !editable && !answered;
5903
+ const awaiting = !decided && !superseded;
5904
+ const skipped = !awaiting && !answered;
5925
5905
  const canEdit = answered && active && !terminal;
5926
5906
  const questions = req.questions;
5927
5907
  const [manualOpen, setManualOpen] = useState7(null);
5928
- const openDefault = editable || answered;
5908
+ const openDefault = awaiting || answered;
5929
5909
  const isOpen = manualOpen ?? openDefault;
5930
5910
  const [showOptions, setShowOptions] = useState7(false);
5931
5911
  const QIcon = questions.length > 1 ? ChatIcon : HelpIcon;
5932
- const identity = editable ? strings.inputRequired : strings.inputBadge;
5912
+ const identity = awaiting ? strings.inputRequired : strings.inputBadge;
5933
5913
  const body = (() => {
5934
- if (editable) {
5914
+ if (awaiting) {
5935
5915
  return /* @__PURE__ */ jsx17(EditableForm, { req, strings, resolve: (reason, ok) => onDecision(part.toolCallId, ok, reason) });
5936
5916
  }
5937
5917
  if (showOptions) {
@@ -5968,7 +5948,7 @@ function ToolAskQuestions({ part, strings, active, superseded = false, onDecisio
5968
5948
  const next = e.currentTarget.open;
5969
5949
  if (next !== isOpen) setManualOpen(next);
5970
5950
  },
5971
- "data-testid": editable ? TID.toolAskQuestions : TID.toolDecision,
5951
+ "data-testid": awaiting ? TID.toolAskQuestions : TID.toolDecision,
5972
5952
  children: [
5973
5953
  /* @__PURE__ */ jsxs14("summary", { class: `${p16}-toolui-head`, children: [
5974
5954
  /* @__PURE__ */ jsxs14("span", { class: `${p16}-toolui-q-pill`, children: [
@@ -5976,13 +5956,16 @@ function ToolAskQuestions({ part, strings, active, superseded = false, onDecisio
5976
5956
  identity
5977
5957
  ] }),
5978
5958
  /* @__PURE__ */ jsxs14("span", { class: `${p16}-toolui-head-end`, children: [
5979
- editable ? null : (
5980
- // Same neutral pill + coloured-icon status as the tool-call card
5981
- // (green check = answered, muted ✕ = skipped) — only the label differs.
5982
- /* @__PURE__ */ jsxs14("span", { class: `${p16}-toolui-badge ${p16}-toolui-status`, "data-status": skipped ? "superseded" : "completed", children: [
5983
- /* @__PURE__ */ jsx17("span", { class: `${p16}-toolui-status-icon`, children: skipped ? /* @__PURE__ */ jsx17(XCircleIcon, {}) : /* @__PURE__ */ jsx17(CheckCircleIcon, {}) }),
5984
- skipped ? strings.inputSkipped : strings.inputAnswered
5985
- ] })
5959
+ awaiting ? null : (
5960
+ // Reuse the tool-call status-pill shell green check = answered, muted ✕ = skipped.
5961
+ /* @__PURE__ */ jsx17(
5962
+ StatusPill,
5963
+ {
5964
+ status: skipped ? "superseded" : "completed",
5965
+ icon: skipped ? /* @__PURE__ */ jsx17(XCircleIcon, {}) : /* @__PURE__ */ jsx17(CheckCircleIcon, {}),
5966
+ label: skipped ? strings.inputSkipped : strings.inputAnswered
5967
+ }
5968
+ )
5986
5969
  ),
5987
5970
  /* @__PURE__ */ jsx17("span", { class: `${p16}-toolui-chevron`, children: /* @__PURE__ */ jsx17(ChevronDownIcon, {}) })
5988
5971
  ] })
@@ -5990,7 +5973,7 @@ function ToolAskQuestions({ part, strings, active, superseded = false, onDecisio
5990
5973
  /* @__PURE__ */ jsxs14("div", { class: `${p16}-toolui-collapse-body`, children: [
5991
5974
  req.intro ? /* @__PURE__ */ jsx17("div", { class: `${p16}-toolui-desc`, children: req.intro }) : null,
5992
5975
  body,
5993
- editable ? null : /* @__PURE__ */ jsxs14(
5976
+ awaiting ? null : /* @__PURE__ */ jsxs14(
5994
5977
  "button",
5995
5978
  {
5996
5979
  type: "button",
@@ -6857,6 +6840,22 @@ function ConversationList({
6857
6840
  // src/ui/suggestions.tsx
6858
6841
  import { jsx as jsx22 } from "preact/jsx-runtime";
6859
6842
  var p19 = BRAND.cssPrefix;
6843
+ function parseSuggestions(data) {
6844
+ const raw = data?.suggestions;
6845
+ if (!Array.isArray(raw)) return [];
6846
+ const out = [];
6847
+ for (const item of raw) {
6848
+ if (!item || typeof item !== "object") continue;
6849
+ const { id, label, text } = item;
6850
+ if (typeof label !== "string" || !label) continue;
6851
+ out.push({
6852
+ id: typeof id === "string" && id ? id : `s${out.length}`,
6853
+ label,
6854
+ text: typeof text === "string" && text ? text : label
6855
+ });
6856
+ }
6857
+ return out;
6858
+ }
6860
6859
  function Suggestions({ suggestions, onPick }) {
6861
6860
  if (suggestions.length === 0) return null;
6862
6861
  return /* @__PURE__ */ jsx22("div", { class: `${p19}-suggestions`, role: "group", "aria-label": "Suggested replies", children: suggestions.map((s, i) => /* @__PURE__ */ jsx22(
@@ -8426,6 +8425,18 @@ function App({ options, hostElement, bus }) {
8426
8425
  useEffect16(() => {
8427
8426
  if (effectiveLocale !== activeLocale) setActiveLocale(effectiveLocale);
8428
8427
  }, [effectiveLocale, activeLocale]);
8428
+ const pendingSuggestionsRef = useRef9(null);
8429
+ const captureSuggestions = useCallback6((chunk) => {
8430
+ if (chunk.type !== "data-suggestions") return false;
8431
+ pendingSuggestionsRef.current = parseSuggestions(chunk.data);
8432
+ return true;
8433
+ }, []);
8434
+ const flushSuggestions = useCallback6(() => {
8435
+ if (pendingSuggestionsRef.current) {
8436
+ setSuggestions(pendingSuggestionsRef.current);
8437
+ pendingSuggestionsRef.current = null;
8438
+ }
8439
+ }, []);
8429
8440
  const adoptConversationRebind = useCallback6(
8430
8441
  (chunk) => {
8431
8442
  if (chunk.type !== "data-conversation-rebind") return false;
@@ -8445,9 +8456,10 @@ function App({ options, hostElement, bus }) {
8445
8456
  const runResume = useCallback6(
8446
8457
  async (handle) => {
8447
8458
  let bubble = null;
8459
+ pendingSuggestionsRef.current = null;
8448
8460
  try {
8449
8461
  for await (const evt of handle.iter) {
8450
- if (adoptConversationRebind(evt.chunk)) continue;
8462
+ if (adoptConversationRebind(evt.chunk) || captureSuggestions(evt.chunk)) continue;
8451
8463
  if (!bubble) {
8452
8464
  bubble = makeAssistantMessage();
8453
8465
  resumeBubbleRef.current = bubble;
@@ -8473,6 +8485,7 @@ function App({ options, hostElement, bus }) {
8473
8485
  bubble.status = "complete";
8474
8486
  feedback.play("messageReceived");
8475
8487
  emitMessage(bus, options, "assistant", assistantText(bubble));
8488
+ flushSuggestions();
8476
8489
  }
8477
8490
  }
8478
8491
  } catch (err) {
@@ -8611,12 +8624,13 @@ function App({ options, hostElement, bus }) {
8611
8624
  userPrefs: persistence.loadUserPrefs()
8612
8625
  });
8613
8626
  setStreaming(true);
8627
+ pendingSuggestionsRef.current = null;
8614
8628
  const handle = transport.sendMessage(body);
8615
8629
  setActiveCancel(() => handle.cancel);
8616
8630
  setActiveDetach(() => handle.detach);
8617
8631
  try {
8618
8632
  for await (const evt of handle.iter) {
8619
- if (adoptConversationRebind(evt.chunk)) continue;
8633
+ if (adoptConversationRebind(evt.chunk) || captureSuggestions(evt.chunk)) continue;
8620
8634
  reducer.apply(evt.chunk);
8621
8635
  if (evt.chunk.type === "finish" && evt.chunk.canContinue === false) {
8622
8636
  setCanSend(false);
@@ -8635,6 +8649,7 @@ function App({ options, hostElement, bus }) {
8635
8649
  assistantMsg.status = "complete";
8636
8650
  feedback.play("messageReceived");
8637
8651
  emitMessage(bus, options, "assistant", assistantText(assistantMsg));
8652
+ flushSuggestions();
8638
8653
  }
8639
8654
  } catch (error) {
8640
8655
  if (isAbortError(error)) {
package/package.json CHANGED
@@ -80,5 +80,5 @@
80
80
  ],
81
81
  "type": "module",
82
82
  "types": "./index.d.ts",
83
- "version": "0.58.1"
83
+ "version": "0.59.0"
84
84
  }
package/schema.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-BAOjO2dQ.js';
1
+ export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-Daefe1g1.js';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
@@ -56,9 +56,9 @@ declare const presentationSchema: z.ZodObject<{
56
56
  inset: z.ZodOptional<z.ZodString>;
57
57
  initialSize: z.ZodDefault<z.ZodEnum<{
58
58
  fullscreen: "fullscreen";
59
- normal: "normal";
60
59
  expanded: "expanded";
61
60
  auto: "auto";
61
+ normal: "normal";
62
62
  }>>;
63
63
  autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
64
64
  }, z.core.$loose>>;
@@ -242,9 +242,9 @@ type LauncherOptions = z.infer<typeof launcherOptionsSchema>;
242
242
 
243
243
  declare const initialSizeSchema: z.ZodEnum<{
244
244
  fullscreen: "fullscreen";
245
- normal: "normal";
246
245
  expanded: "expanded";
247
246
  auto: "auto";
247
+ normal: "normal";
248
248
  }>;
249
249
  declare const resizeOptionsSchema: z.ZodObject<{
250
250
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -271,9 +271,9 @@ declare const sizeOptionsSchema: z.ZodObject<{
271
271
  inset: z.ZodOptional<z.ZodString>;
272
272
  initialSize: z.ZodDefault<z.ZodEnum<{
273
273
  fullscreen: "fullscreen";
274
- normal: "normal";
275
274
  expanded: "expanded";
276
275
  auto: "auto";
276
+ normal: "normal";
277
277
  }>>;
278
278
  autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
279
279
  }, z.core.$loose>;
@@ -325,40 +325,40 @@ type FeatureFlags = z.infer<typeof featureFlagsSchema>;
325
325
  */
326
326
 
327
327
  declare const actionNameSchema: z.ZodEnum<{
328
+ close: "close";
328
329
  expand: "expand";
329
330
  fullscreen: "fullscreen";
330
- close: "close";
331
- language: "language";
331
+ clear: "clear";
332
332
  theme: "theme";
333
+ language: "language";
333
334
  textSize: "textSize";
334
335
  history: "history";
335
- clear: "clear";
336
336
  sound: "sound";
337
337
  }>;
338
338
  type ActionName = z.infer<typeof actionNameSchema>;
339
339
  declare const headerActionsSchema: z.ZodArray<z.ZodEnum<{
340
+ close: "close";
340
341
  expand: "expand";
341
342
  fullscreen: "fullscreen";
342
- close: "close";
343
- language: "language";
343
+ clear: "clear";
344
344
  theme: "theme";
345
+ language: "language";
345
346
  textSize: "textSize";
346
347
  history: "history";
347
- clear: "clear";
348
348
  sound: "sound";
349
349
  }>>;
350
350
  type HeaderActions = z.infer<typeof headerActionsSchema>;
351
351
  /** Section wrapper — `actions` list wrapped under `header` in the dashboard form. */
352
352
  declare const headerSchema: z.ZodObject<{
353
353
  actions: z.ZodOptional<z.ZodArray<z.ZodEnum<{
354
+ close: "close";
354
355
  expand: "expand";
355
356
  fullscreen: "fullscreen";
356
- close: "close";
357
- language: "language";
357
+ clear: "clear";
358
358
  theme: "theme";
359
+ language: "language";
359
360
  textSize: "textSize";
360
361
  history: "history";
361
- clear: "clear";
362
362
  sound: "sound";
363
363
  }>>>;
364
364
  }, z.core.$loose>;
@@ -374,33 +374,33 @@ type HeaderOptions = z.infer<typeof headerSchema>;
374
374
  */
375
375
 
376
376
  declare const feedbackEventSchema: z.ZodEnum<{
377
+ voiceStart: "voiceStart";
378
+ voiceStop: "voiceStop";
377
379
  error: "error";
378
380
  messageReceived: "messageReceived";
379
381
  messageSent: "messageSent";
380
- voiceStart: "voiceStart";
381
- voiceStop: "voiceStop";
382
382
  }>;
383
383
  type FeedbackEvent = z.infer<typeof feedbackEventSchema>;
384
384
  declare const soundOptionsSchema: z.ZodObject<{
385
385
  enabled: z.ZodDefault<z.ZodBoolean>;
386
386
  volume: z.ZodDefault<z.ZodNumber>;
387
387
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
388
+ voiceStart: "voiceStart";
389
+ voiceStop: "voiceStop";
388
390
  error: "error";
389
391
  messageReceived: "messageReceived";
390
392
  messageSent: "messageSent";
391
- voiceStart: "voiceStart";
392
- voiceStop: "voiceStop";
393
393
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
394
394
  }, z.core.$loose>;
395
395
  type SoundOptions = z.infer<typeof soundOptionsSchema>;
396
396
  declare const hapticsOptionsSchema: z.ZodObject<{
397
397
  enabled: z.ZodDefault<z.ZodBoolean>;
398
398
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
399
+ voiceStart: "voiceStart";
400
+ voiceStop: "voiceStop";
399
401
  error: "error";
400
402
  messageReceived: "messageReceived";
401
403
  messageSent: "messageSent";
402
- voiceStart: "voiceStart";
403
- voiceStop: "voiceStop";
404
404
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
405
405
  }, z.core.$loose>;
406
406
  type HapticsOptions = z.infer<typeof hapticsOptionsSchema>;
@@ -409,21 +409,21 @@ declare const feedbackSchema: z.ZodObject<{
409
409
  enabled: z.ZodDefault<z.ZodBoolean>;
410
410
  volume: z.ZodDefault<z.ZodNumber>;
411
411
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
412
+ voiceStart: "voiceStart";
413
+ voiceStop: "voiceStop";
412
414
  error: "error";
413
415
  messageReceived: "messageReceived";
414
416
  messageSent: "messageSent";
415
- voiceStart: "voiceStart";
416
- voiceStop: "voiceStop";
417
417
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
418
418
  }, z.core.$loose>>;
419
419
  haptics: z.ZodOptional<z.ZodObject<{
420
420
  enabled: z.ZodDefault<z.ZodBoolean>;
421
421
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
422
+ voiceStart: "voiceStart";
423
+ voiceStop: "voiceStop";
422
424
  error: "error";
423
425
  messageReceived: "messageReceived";
424
426
  messageSent: "messageSent";
425
- voiceStart: "voiceStart";
426
- voiceStop: "voiceStop";
427
427
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
428
428
  }, z.core.$loose>>;
429
429
  }, z.core.$loose>;
@@ -858,18 +858,18 @@ type I18nOptions = z.infer<typeof i18nSchema>;
858
858
  */
859
859
 
860
860
  declare const moduleLayoutSchema: z.ZodEnum<{
861
+ home: "home";
861
862
  chat: "chat";
862
863
  help: "help";
863
- home: "home";
864
864
  news: "news";
865
865
  }>;
866
866
  type ModuleLayout = z.infer<typeof moduleLayoutSchema>;
867
867
  declare const moduleSchema: z.ZodObject<{
868
868
  label: z.ZodString;
869
869
  layout: z.ZodEnum<{
870
+ home: "home";
870
871
  chat: "chat";
871
872
  help: "help";
872
- home: "home";
873
873
  news: "news";
874
874
  }>;
875
875
  contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -895,9 +895,9 @@ type ModuleOptions = z.infer<typeof moduleSchema>;
895
895
  declare const modulesSchema: z.ZodArray<z.ZodObject<{
896
896
  label: z.ZodString;
897
897
  layout: z.ZodEnum<{
898
+ home: "home";
898
899
  chat: "chat";
899
900
  help: "help";
900
- home: "home";
901
901
  news: "news";
902
902
  }>;
903
903
  contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;