@helpai/elements 0.53.0 → 0.54.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.mjs CHANGED
@@ -29,7 +29,7 @@ var BRAND = {
29
29
  };
30
30
 
31
31
  // src/core/version.ts
32
- var ELEMENTS_VERSION = true ? "0.53.0" : "0.0.0-dev";
32
+ var ELEMENTS_VERSION = true ? "0.54.0" : "0.0.0-dev";
33
33
  var ELEMENTS_VERSION_PARAM = "_ev";
34
34
 
35
35
  // src/i18n/strings.ts
@@ -116,7 +116,7 @@ var STRINGS_EN = {
116
116
  newsLoading: "Loading news\u2026",
117
117
  newsBack: "Back to news",
118
118
  newsPublishedAt: "Published {date}",
119
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
119
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
120
120
  formSubmit: "Submit",
121
121
  formSkip: "Maybe later",
122
122
  formSubmitted: "Completed",
@@ -136,26 +136,15 @@ var STRINGS_EN = {
136
136
  formChooseAtMost: "Choose at most {max}",
137
137
  formOther: "Other",
138
138
  formOtherPlaceholder: "Type your answer\u2026",
139
- inputRequired: "User Input Required",
140
- inputBadge: "User Input",
139
+ inputRequired: "Questions for you",
140
+ inputBadge: "Questions",
141
141
  inputAnswered: "Answered",
142
142
  inputSkipped: "Skipped",
143
- inputQuestion: "Question",
144
- inputYourAnswer: "Your answer",
145
- inputSubmit: "Submit answer",
143
+ inputSubmit: "Submit answers",
146
144
  inputSubmitHint: "Enter to send \xB7 Shift+Enter = new line",
147
- inputAnswerPlaceholder: "Type your answer\u2026",
148
145
  inputSkip: "Skip",
149
146
  confirmYes: "Yes",
150
147
  confirmNo: "No",
151
- inputConfirmHint: "Choose yes or no.",
152
- inputOptionalNote: "Optional note",
153
- inputOptionalNotePlaceholder: "Optional comment\u2026",
154
- inputSubmitted: "Answer submitted",
155
- respFreeText: "Free Text",
156
- respSingleChoice: "Single Choice",
157
- respMultiChoice: "Multiple Choice",
158
- respConfirmation: "Confirmation",
159
148
  approvalRequired: "Approval required",
160
149
  approve: "Approve",
161
150
  reject: "Reject",
@@ -260,7 +249,7 @@ var STRINGS_FR = {
260
249
  newsLoading: "Chargement des actualit\xE9s\u2026",
261
250
  newsBack: "Retour aux actualit\xE9s",
262
251
  newsPublishedAt: "Publi\xE9 le {date}",
263
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
252
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
264
253
  formSubmit: "Envoyer",
265
254
  formSkip: "Plus tard",
266
255
  formSubmitted: "Termin\xE9",
@@ -280,26 +269,15 @@ var STRINGS_FR = {
280
269
  formChooseAtMost: "Choisissez au plus {max}",
281
270
  formOther: "Autre",
282
271
  formOtherPlaceholder: "Saisissez votre r\xE9ponse\u2026",
283
- inputRequired: "Saisie requise",
284
- inputBadge: "Saisie",
272
+ inputRequired: "Questions pour vous",
273
+ inputBadge: "Questions",
285
274
  inputAnswered: "R\xE9pondu",
286
275
  inputSkipped: "Ignor\xE9",
287
- inputQuestion: "Question",
288
- inputYourAnswer: "Votre r\xE9ponse",
289
- inputSubmit: "Envoyer la r\xE9ponse",
276
+ inputSubmit: "Envoyer les r\xE9ponses",
290
277
  inputSubmitHint: "Entr\xE9e pour envoyer \xB7 Maj+Entr\xE9e = saut de ligne",
291
- inputAnswerPlaceholder: "Saisissez votre r\xE9ponse\u2026",
292
278
  inputSkip: "Ignorer",
293
279
  confirmYes: "Oui",
294
280
  confirmNo: "Non",
295
- inputConfirmHint: "Choisissez oui ou non.",
296
- inputOptionalNote: "Note facultative",
297
- inputOptionalNotePlaceholder: "Commentaire facultatif\u2026",
298
- inputSubmitted: "R\xE9ponse envoy\xE9e",
299
- respFreeText: "Texte libre",
300
- respSingleChoice: "Choix unique",
301
- respMultiChoice: "Choix multiple",
302
- respConfirmation: "Confirmation",
303
281
  approvalRequired: "Approbation requise",
304
282
  approve: "Approuver",
305
283
  reject: "Refuser",
@@ -404,7 +382,7 @@ var STRINGS_AR = {
404
382
  newsLoading: "\u062C\u0627\u0631\u064D \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0623\u062E\u0628\u0627\u0631\u2026",
405
383
  newsBack: "\u0627\u0644\u0639\u0648\u062F\u0629 \u0625\u0644\u0649 \u0627\u0644\u0623\u062E\u0628\u0627\u0631",
406
384
  newsPublishedAt: "\u0646\u064F\u0634\u0631 \u0641\u064A {date}",
407
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
385
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
408
386
  formSubmit: "\u0625\u0631\u0633\u0627\u0644",
409
387
  formSkip: "\u0644\u0627\u062D\u0642\u064B\u0627",
410
388
  formSubmitted: "\u062A\u0645",
@@ -424,26 +402,15 @@ var STRINGS_AR = {
424
402
  formChooseAtMost: "\u0627\u062E\u062A\u0631 {max} \u0639\u0644\u0649 \u0627\u0644\u0623\u0643\u062B\u0631",
425
403
  formOther: "\u0623\u062E\u0631\u0649",
426
404
  formOtherPlaceholder: "\u0627\u0643\u062A\u0628 \u0625\u062C\u0627\u0628\u062A\u0643\u2026",
427
- inputRequired: "\u0645\u0637\u0644\u0648\u0628 \u0625\u062F\u062E\u0627\u0644 \u0645\u0646 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645",
428
- inputBadge: "\u0625\u062F\u062E\u0627\u0644 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645",
405
+ inputRequired: "\u0623\u0633\u0626\u0644\u0629 \u0644\u0643",
406
+ inputBadge: "\u0623\u0633\u0626\u0644\u0629",
429
407
  inputAnswered: "\u062A\u0645\u062A \u0627\u0644\u0625\u062C\u0627\u0628\u0629",
430
408
  inputSkipped: "\u062A\u0645 \u0627\u0644\u062A\u062E\u0637\u064A",
431
- inputQuestion: "\u0627\u0644\u0633\u0624\u0627\u0644",
432
- inputYourAnswer: "\u0625\u062C\u0627\u0628\u062A\u0643",
433
- inputSubmit: "\u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0625\u062C\u0627\u0628\u0629",
409
+ inputSubmit: "\u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0625\u062C\u0627\u0628\u0627\u062A",
434
410
  inputSubmitHint: "Enter \u0644\u0644\u0625\u0631\u0633\u0627\u0644 \xB7 Shift+Enter = \u0633\u0637\u0631 \u062C\u062F\u064A\u062F",
435
- inputAnswerPlaceholder: "\u0627\u0643\u062A\u0628 \u0625\u062C\u0627\u0628\u062A\u0643\u2026",
436
411
  inputSkip: "\u062A\u062E\u0637\u064D\u0651",
437
412
  confirmYes: "\u0646\u0639\u0645",
438
413
  confirmNo: "\u0644\u0627",
439
- inputConfirmHint: "\u0627\u062E\u062A\u0631 \u0646\u0639\u0645 \u0623\u0648 \u0644\u0627.",
440
- inputOptionalNote: "\u0645\u0644\u0627\u062D\u0638\u0629 \u0627\u062E\u062A\u064A\u0627\u0631\u064A\u0629",
441
- inputOptionalNotePlaceholder: "\u062A\u0639\u0644\u064A\u0642 \u0627\u062E\u062A\u064A\u0627\u0631\u064A\u2026",
442
- inputSubmitted: "\u062A\u0645 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0625\u062C\u0627\u0628\u0629",
443
- respFreeText: "\u0646\u0635 \u062D\u0631",
444
- respSingleChoice: "\u0627\u062E\u062A\u064A\u0627\u0631 \u0648\u0627\u062D\u062F",
445
- respMultiChoice: "\u0627\u062E\u062A\u064A\u0627\u0631 \u0645\u062A\u0639\u062F\u062F",
446
- respConfirmation: "\u062A\u0623\u0643\u064A\u062F",
447
414
  approvalRequired: "\u0645\u0637\u0644\u0648\u0628 \u0645\u0648\u0627\u0641\u0642\u0629",
448
415
  approve: "\u0645\u0648\u0627\u0641\u0642\u0629",
449
416
  reject: "\u0631\u0641\u0636",
@@ -548,7 +515,7 @@ var STRINGS_ES = {
548
515
  newsLoading: "Cargando novedades\u2026",
549
516
  newsBack: "Volver a novedades",
550
517
  newsPublishedAt: "Publicado el {date}",
551
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
518
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
552
519
  formSubmit: "Enviar",
553
520
  formSkip: "Quiz\xE1 m\xE1s tarde",
554
521
  formSubmitted: "Completado",
@@ -568,26 +535,15 @@ var STRINGS_ES = {
568
535
  formChooseAtMost: "Elige como m\xE1ximo {max}",
569
536
  formOther: "Otro",
570
537
  formOtherPlaceholder: "Escribe tu respuesta\u2026",
571
- inputRequired: "Entrada requerida",
572
- inputBadge: "Entrada",
538
+ inputRequired: "Preguntas para ti",
539
+ inputBadge: "Preguntas",
573
540
  inputAnswered: "Respondido",
574
541
  inputSkipped: "Omitido",
575
- inputQuestion: "Pregunta",
576
- inputYourAnswer: "Tu respuesta",
577
- inputSubmit: "Enviar respuesta",
542
+ inputSubmit: "Enviar respuestas",
578
543
  inputSubmitHint: "Enter para enviar \xB7 May\xFAs+Enter = nueva l\xEDnea",
579
- inputAnswerPlaceholder: "Escribe tu respuesta\u2026",
580
544
  inputSkip: "Omitir",
581
545
  confirmYes: "S\xED",
582
546
  confirmNo: "No",
583
- inputConfirmHint: "Elige s\xED o no.",
584
- inputOptionalNote: "Nota opcional",
585
- inputOptionalNotePlaceholder: "Comentario opcional\u2026",
586
- inputSubmitted: "Respuesta enviada",
587
- respFreeText: "Texto libre",
588
- respSingleChoice: "Opci\xF3n \xFAnica",
589
- respMultiChoice: "Opci\xF3n m\xFAltiple",
590
- respConfirmation: "Confirmaci\xF3n",
591
547
  approvalRequired: "Aprobaci\xF3n requerida",
592
548
  approve: "Aprobar",
593
549
  reject: "Rechazar",
@@ -692,7 +648,7 @@ var STRINGS_HE = {
692
648
  newsLoading: "\u05D8\u05D5\u05E2\u05DF \u05D7\u05D3\u05E9\u05D5\u05EA\u2026",
693
649
  newsBack: "\u05D7\u05D6\u05E8\u05D4 \u05DC\u05D7\u05D3\u05E9\u05D5\u05EA",
694
650
  newsPublishedAt: "\u05E4\u05D5\u05E8\u05E1\u05DD \u05D1-{date}",
695
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
651
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
696
652
  formSubmit: "\u05E9\u05DC\u05D9\u05D7\u05D4",
697
653
  formSkip: "\u05D0\u05D7\u05E8 \u05DB\u05DA",
698
654
  formSubmitted: "\u05E0\u05E9\u05DC\u05D7",
@@ -712,26 +668,15 @@ var STRINGS_HE = {
712
668
  formChooseAtMost: "\u05D1\u05D7\u05E8 \u05DC\u05DB\u05DC \u05D4\u05D9\u05D5\u05EA\u05E8 {max}",
713
669
  formOther: "\u05D0\u05D7\u05E8",
714
670
  formOtherPlaceholder: "\u05DB\u05EA\u05D5\u05D1 \u05D0\u05EA \u05EA\u05E9\u05D5\u05D1\u05EA\u05DA\u2026",
715
- inputRequired: "\u05E0\u05D3\u05E8\u05E9 \u05E7\u05DC\u05D8 \u05DE\u05D4\u05DE\u05E9\u05EA\u05DE\u05E9",
716
- inputBadge: "\u05E7\u05DC\u05D8 \u05DE\u05E9\u05EA\u05DE\u05E9",
671
+ inputRequired: "\u05E9\u05D0\u05DC\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8\u05DA",
672
+ inputBadge: "\u05E9\u05D0\u05DC\u05D5\u05EA",
717
673
  inputAnswered: "\u05E0\u05E2\u05E0\u05D4",
718
674
  inputSkipped: "\u05D3\u05D5\u05DC\u05D2",
719
- inputQuestion: "\u05E9\u05D0\u05DC\u05D4",
720
- inputYourAnswer: "\u05D4\u05EA\u05E9\u05D5\u05D1\u05D4 \u05E9\u05DC\u05DA",
721
- inputSubmit: "\u05E9\u05DC\u05D9\u05D7\u05EA \u05EA\u05E9\u05D5\u05D1\u05D4",
675
+ inputSubmit: "\u05E9\u05DC\u05D9\u05D7\u05EA \u05EA\u05E9\u05D5\u05D1\u05D5\u05EA",
722
676
  inputSubmitHint: "Enter \u05DC\u05E9\u05DC\u05D9\u05D7\u05D4 \xB7 Shift+Enter = \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
723
- inputAnswerPlaceholder: "\u05DB\u05EA\u05D5\u05D1 \u05D0\u05EA \u05EA\u05E9\u05D5\u05D1\u05EA\u05DA\u2026",
724
677
  inputSkip: "\u05D3\u05D9\u05DC\u05D5\u05D2",
725
678
  confirmYes: "\u05DB\u05DF",
726
679
  confirmNo: "\u05DC\u05D0",
727
- inputConfirmHint: "\u05D1\u05D7\u05E8 \u05DB\u05DF \u05D0\u05D5 \u05DC\u05D0.",
728
- inputOptionalNote: "\u05D4\u05E2\u05E8\u05D4 \u05D0\u05D5\u05E4\u05E6\u05D9\u05D5\u05E0\u05DC\u05D9\u05EA",
729
- inputOptionalNotePlaceholder: "\u05D4\u05E2\u05E8\u05D4 \u05D0\u05D5\u05E4\u05E6\u05D9\u05D5\u05E0\u05DC\u05D9\u05EA\u2026",
730
- inputSubmitted: "\u05D4\u05EA\u05E9\u05D5\u05D1\u05D4 \u05E0\u05E9\u05DC\u05D7\u05D4",
731
- respFreeText: "\u05D8\u05E7\u05E1\u05D8 \u05D7\u05D5\u05E4\u05E9\u05D9",
732
- respSingleChoice: "\u05D1\u05D7\u05D9\u05E8\u05D4 \u05D9\u05D7\u05D9\u05D3\u05D4",
733
- respMultiChoice: "\u05D1\u05D7\u05D9\u05E8\u05D4 \u05DE\u05E8\u05D5\u05D1\u05D4",
734
- respConfirmation: "\u05D0\u05D9\u05E9\u05D5\u05E8",
735
680
  approvalRequired: "\u05E0\u05D3\u05E8\u05E9 \u05D0\u05D9\u05E9\u05D5\u05E8",
736
681
  approve: "\u05D0\u05D9\u05E9\u05D5\u05E8",
737
682
  reject: "\u05D3\u05D7\u05D9\u05D9\u05D4",
@@ -1912,7 +1857,7 @@ var EventBus = class {
1912
1857
  import { h, render as renderPreact } from "preact";
1913
1858
 
1914
1859
  // src/ui/app.tsx
1915
- import { useCallback as useCallback6, useEffect as useEffect16, useLayoutEffect as useLayoutEffect3, useMemo as useMemo3, useRef as useRef9, useState as useState14 } from "preact/hooks";
1860
+ import { useCallback as useCallback6, useEffect as useEffect16, useLayoutEffect as useLayoutEffect3, useMemo as useMemo3, useRef as useRef9, useState as useState13 } from "preact/hooks";
1916
1861
  import { batch, useComputed as useComputed8, useSignal } from "@preact/signals";
1917
1862
 
1918
1863
  // src/core/handshake-shape.ts
@@ -3819,7 +3764,7 @@ var TID = {
3819
3764
  helpArticle: `${p2}-help-article`,
3820
3765
  /** News list item — suffix `-{id}`. */
3821
3766
  newsItem: `${p2}-news-item`,
3822
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ─────
3767
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ─────
3823
3768
  /** Form gate root — a timeline row that locks the chat while open. */
3824
3769
  formGate: `${p2}-form-gate`,
3825
3770
  /** "Form submitted / skipped" marker row (wire-reconstructed on resume). */
@@ -3836,11 +3781,11 @@ var TID = {
3836
3781
  formSkip: `${p2}-form-skip`,
3837
3782
  /** A single form field control — suffix `-{name}` at the JSX site. */
3838
3783
  formField: `${p2}-form-field`,
3839
- /** Ask-input tool root (inline form in a message bubble). */
3840
- toolAskInput: `${p2}-tool-ask-input`,
3841
- /** Ask-input submit button. */
3784
+ /** Ask-questions tool root (inline form in a message bubble). */
3785
+ toolAskQuestions: `${p2}-tool-ask-questions`,
3786
+ /** Ask-questions submit button. */
3842
3787
  toolInputSubmit: `${p2}-tool-input-submit`,
3843
- /** Ask-input skip button. */
3788
+ /** Ask-questions skip/cancel button. */
3844
3789
  toolInputSkip: `${p2}-tool-input-skip`,
3845
3790
  /** Tool-approval root (approve/reject prompt). */
3846
3791
  toolApproval: `${p2}-tool-approval`,
@@ -4047,7 +3992,7 @@ var KEEP_VISIBLE = 56;
4047
3992
  function useDragMove(panelEl, enabled) {
4048
3993
  useEffect3(() => {
4049
3994
  if (!enabled || !panelEl) return;
4050
- const num2 = (v) => Number.parseFloat(v) || 0;
3995
+ const num = (v) => Number.parseFloat(v) || 0;
4051
3996
  const clamp = (v, max) => Math.min(max, Math.max(-max, v));
4052
3997
  let drag = null;
4053
3998
  const onDown = (e) => {
@@ -4058,8 +4003,8 @@ function useDragMove(panelEl, enabled) {
4058
4003
  id: e.pointerId,
4059
4004
  x: e.clientX,
4060
4005
  y: e.clientY,
4061
- dx: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
4062
- dy: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
4006
+ dx: num(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
4007
+ dy: num(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
4063
4008
  // Centred origin: |offset| ≤ (viewport + panel)/2 − keepVisible keeps a
4064
4009
  // strip of the dialog reachable so it can never be lost off-screen.
4065
4010
  maxX: (window.innerWidth + rect.width) / 2 - KEEP_VISIBLE,
@@ -4992,7 +4937,7 @@ function HeaderActions({ panelProps, variant }) {
4992
4937
  }
4993
4938
 
4994
4939
  // src/ui/message-list.tsx
4995
- import { useEffect as useEffect7, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState7 } from "preact/hooks";
4940
+ import { useEffect as useEffect7, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState6 } from "preact/hooks";
4996
4941
  import { useComputed as useComputed6 } from "@preact/signals";
4997
4942
 
4998
4943
  // src/ui/form/dynamic-form.tsx
@@ -5392,10 +5337,10 @@ function FormDoneMarker({
5392
5337
  import { useComputed as useComputed5 } from "@preact/signals";
5393
5338
 
5394
5339
  // src/stream/constants.ts
5395
- function isAskUserInputTool(toolName2) {
5340
+ function isAskUserQuestionsTool(toolName2) {
5396
5341
  if (!toolName2) return false;
5397
5342
  const name = toolName2.startsWith("tool:") ? toolName2.slice(5) : toolName2;
5398
- return name === "ask-user-input" || name === "ask_user_input" || name === "request-user-input" || name === "request_user_input";
5343
+ return name === "ask-user-questions" || name === "ask_user_questions";
5399
5344
  }
5400
5345
 
5401
5346
  // src/ui/markdown.tsx
@@ -5662,107 +5607,103 @@ function ToolApproval({ part, strings, active, superseded = false, onDecision, o
5662
5607
  ] });
5663
5608
  }
5664
5609
 
5665
- // src/ui/tool-ask-input.tsx
5610
+ // src/ui/tool-ask-questions.tsx
5666
5611
  import { useComputed as useComputed3 } from "@preact/signals";
5667
- import { useState as useState6 } from "preact/hooks";
5668
5612
 
5669
5613
  // src/ui/form/field.ts
5670
- function parseAskUserInput(input) {
5614
+ var QUESTION_TYPES = /* @__PURE__ */ new Set([
5615
+ "text",
5616
+ "email",
5617
+ "phone",
5618
+ "number",
5619
+ "date",
5620
+ "single-select",
5621
+ "multi-select",
5622
+ "boolean"
5623
+ ]);
5624
+ function parseAskUserQuestions(input) {
5671
5625
  const raw = input && typeof input === "object" ? input : {};
5672
- const responseType = raw.responseType;
5626
+ const rawQuestions = Array.isArray(raw.questions) ? raw.questions : [];
5627
+ const questions = rawQuestions.map(parseQuestion).filter((q) => q !== null);
5628
+ return { intro: str(raw.intro), questions };
5629
+ }
5630
+ function parseQuestion(value, index) {
5631
+ if (!value || typeof value !== "object") return null;
5632
+ const raw = value;
5633
+ const type = QUESTION_TYPES.has(raw.type) ? raw.type : "text";
5673
5634
  return {
5674
- title: str(raw.title),
5635
+ key: str(raw.key) ?? `q${index + 1}`,
5675
5636
  question: str(raw.question) ?? "Please provide the missing information.",
5676
- description: str(raw.description),
5677
- placeholder: str(raw.placeholder),
5678
- responseType: responseType === "single-choice" || responseType === "multi-choice" || responseType === "confirmation" || responseType === "free-text" ? responseType : "free-text",
5679
- choices: Array.isArray(raw.choices) ? raw.choices : void 0,
5680
- allowOther: typeof raw.allowOther === "boolean" ? raw.allowOther : void 0,
5681
- required: typeof raw.required === "boolean" ? raw.required : true,
5682
- defaultValues: Array.isArray(raw.defaultValues) ? raw.defaultValues.filter((v) => typeof v === "string") : void 0,
5683
- minSelections: num(raw.minSelections),
5684
- maxSelections: num(raw.maxSelections),
5685
- validationHint: str(raw.validationHint)
5637
+ type,
5638
+ options: Array.isArray(raw.options) ? raw.options.filter((o) => typeof o === "string" && o.trim().length > 0) : void 0,
5639
+ required: typeof raw.required === "boolean" ? raw.required : void 0,
5640
+ helpText: str(raw.helpText)
5686
5641
  };
5687
5642
  }
5688
- function askInputToFields(req) {
5689
- if (req.responseType === "confirmation") return [];
5690
- const options = (req.choices ?? []).map(normalizeChoice).filter((c) => c !== null);
5691
- let type = "textarea";
5692
- if (req.responseType === "single-choice" && options.length > 0) type = "radio";
5693
- else if (req.responseType === "multi-choice") type = "multiselect";
5694
- const defaultValue = type === "multiselect" ? req.defaultValues?.join(", ") : req.defaultValues?.[0];
5695
- return [
5696
- {
5697
- name: "answer",
5698
- label: req.question,
5643
+ function fieldTypeFor(type) {
5644
+ switch (type) {
5645
+ case "text":
5646
+ return "textarea";
5647
+ case "phone":
5648
+ return "tel";
5649
+ case "single-select":
5650
+ case "boolean":
5651
+ return "radio";
5652
+ case "multi-select":
5653
+ return "multiselect";
5654
+ default:
5655
+ return type;
5656
+ }
5657
+ }
5658
+ function askQuestionsToFields(req, yesLabel, noLabel) {
5659
+ return req.questions.map((q) => {
5660
+ const type = fieldTypeFor(q.type);
5661
+ const options = q.type === "boolean" ? [
5662
+ { value: "yes", label: yesLabel },
5663
+ { value: "no", label: noLabel }
5664
+ ] : (q.options ?? []).map((o) => ({ value: o, label: o }));
5665
+ return {
5666
+ name: q.key,
5667
+ label: q.question,
5699
5668
  type,
5700
- placeholder: req.placeholder,
5701
- required: req.required ?? true,
5702
- defaultValue,
5669
+ required: q.required ?? false,
5703
5670
  options: options.length > 0 ? options : void 0,
5704
- allowOther: req.allowOther,
5705
- validationHint: req.validationHint,
5706
- validation: type === "multiselect" ? { minSelections: req.minSelections, maxSelections: req.maxSelections } : void 0
5707
- }
5708
- ];
5709
- }
5710
- function normalizeChoice(c) {
5711
- if (typeof c === "string") return c ? { value: c, label: c } : null;
5712
- if (c && typeof c.value === "string" && c.value)
5713
- return { value: c.value, label: c.label ?? c.value, description: c.description };
5714
- return null;
5671
+ validationHint: q.helpText
5672
+ };
5673
+ });
5715
5674
  }
5716
5675
  function str(v) {
5717
5676
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
5718
5677
  }
5719
- function num(v) {
5720
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
5721
- }
5722
5678
 
5723
- // src/ui/tool-ask-input.tsx
5679
+ // src/ui/tool-ask-questions.tsx
5724
5680
  import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs13 } from "preact/jsx-runtime";
5725
5681
  var p15 = BRAND.cssPrefix;
5726
- function responseTypeLabel(req, s) {
5727
- switch (req.responseType) {
5728
- case "single-choice":
5729
- return s.respSingleChoice;
5730
- case "multi-choice":
5731
- return s.respMultiChoice;
5732
- case "confirmation":
5733
- return s.respConfirmation;
5734
- default:
5735
- return s.respFreeText;
5736
- }
5737
- }
5738
- function ToolAskInput({ part, strings, active, superseded = false, onSubmit, onDecision, onEdit }) {
5682
+ function ToolAskQuestions({ part, strings, active, superseded = false, onDecision, onEdit }) {
5739
5683
  const state = useComputed3(() => part.stateSig.value);
5740
5684
  const approval = useComputed3(() => part.approvalSig.value);
5741
- const request = useComputed3(() => parseAskUserInput(part.inputSig.value));
5685
+ const request = useComputed3(() => parseAskUserQuestions(part.inputSig.value));
5742
5686
  const { terminal, responded, decided } = toolDecisionState(state.value, approval.value);
5743
- const viaApproval = approval.value !== void 0;
5744
- const resolve = (answer, accepted) => {
5745
- if (viaApproval) onDecision(part.toolCallId, accepted, answer);
5746
- else if (request.value.responseType === "confirmation") onSubmit(part.toolCallId, { confirmed: accepted });
5747
- else onSubmit(part.toolCallId, accepted ? { answer } : {});
5748
- };
5749
5687
  const req = request.value;
5750
5688
  if (decided) {
5751
5689
  const editable = responded && active && !terminal;
5752
5690
  return /* @__PURE__ */ jsx16(DecidedCard, { part, strings, req, editable, onEdit: () => onEdit(part.toolCallId) });
5753
5691
  }
5754
5692
  const stale = superseded;
5755
- return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui${stale ? ` ${p15}-toolui-stale` : ""}`, "data-testid": TID.toolAskInput, children: [
5693
+ return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui${stale ? ` ${p15}-toolui-stale` : ""}`, "data-testid": TID.toolAskQuestions, children: [
5756
5694
  /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-head`, children: stale ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
5757
5695
  /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-accent`, children: strings.inputBadge }),
5758
5696
  /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-muted`, children: strings.statusSuperseded })
5759
- ] }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
5760
- /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-accent`, children: strings.inputRequired }),
5761
- /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge`, children: responseTypeLabel(req, strings) })
5762
- ] }) }),
5763
- req.description ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-desc`, children: req.description }) : null,
5764
- /* @__PURE__ */ jsx16(Section, { label: strings.inputQuestion, text: req.question }),
5765
- stale ? null : /* @__PURE__ */ jsx16(AskBody, { req, strings, resolve })
5697
+ ] }) : /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-accent`, children: strings.inputRequired }) }),
5698
+ req.intro ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-desc`, children: req.intro }) : null,
5699
+ stale ? null : /* @__PURE__ */ jsx16(
5700
+ AskBody,
5701
+ {
5702
+ req,
5703
+ strings,
5704
+ resolve: (reason, accepted) => onDecision(part.toolCallId, accepted, reason)
5705
+ }
5706
+ )
5766
5707
  ] });
5767
5708
  }
5768
5709
  function AskBody({
@@ -5770,72 +5711,32 @@ function AskBody({
5770
5711
  strings,
5771
5712
  resolve
5772
5713
  }) {
5773
- if (req.responseType === "confirmation") {
5774
- return /* @__PURE__ */ jsx16(ConfirmBody, { req, strings, resolve });
5775
- }
5776
- const fields = askInputToFields(req).map((f) => {
5777
- f.label = strings.inputYourAnswer;
5778
- f.placeholder = f.placeholder ?? strings.inputAnswerPlaceholder;
5779
- return f;
5780
- });
5714
+ const fields = askQuestionsToFields(req, strings.confirmYes, strings.confirmNo);
5715
+ const loneTextarea = req.questions.length === 1 && req.questions[0]?.type === "text";
5781
5716
  return /* @__PURE__ */ jsx16(
5782
5717
  DynamicForm,
5783
5718
  {
5784
5719
  fields,
5785
5720
  strings,
5786
5721
  submitLabel: strings.inputSubmit,
5787
- footerHint: req.responseType === "free-text" ? strings.inputSubmitHint : void 0,
5788
- onSubmit: (values) => resolve(values.answer ?? Object.values(values).join(", "), true),
5722
+ footerHint: loneTextarea ? strings.inputSubmitHint : void 0,
5723
+ onSubmit: (values) => resolve(buildAnswersReason(req.questions, values), true),
5789
5724
  skipLabel: strings.inputSkip,
5790
5725
  onSkip: () => resolve(void 0, false),
5791
- submitOnEnter: true,
5726
+ submitOnEnter: loneTextarea,
5792
5727
  submitTestId: TID.toolInputSubmit,
5793
5728
  skipTestId: TID.toolInputSkip
5794
5729
  }
5795
5730
  );
5796
5731
  }
5797
- function ConfirmBody({
5798
- req,
5799
- strings,
5800
- resolve
5801
- }) {
5802
- const [note, setNote] = useState6("");
5803
- const supportsNote = req.allowOther ?? true;
5804
- const yes = () => resolve(note.trim() || void 0, true);
5805
- const no = () => resolve(void 0, false);
5806
- const onKeyDown = (e) => {
5807
- if (e.key !== "Enter" || e.shiftKey || e.isComposing) return;
5808
- e.preventDefault();
5809
- yes();
5810
- };
5811
- return /* @__PURE__ */ jsxs13(Fragment4, { children: [
5812
- supportsNote ? /* @__PURE__ */ jsxs13("label", { class: `${p15}-field`, children: [
5813
- /* @__PURE__ */ jsx16("span", { class: `${p15}-field-label`, children: strings.inputOptionalNote }),
5814
- /* @__PURE__ */ jsx16(
5815
- "textarea",
5816
- {
5817
- class: `${p15}-field-input`,
5818
- rows: 2,
5819
- value: note,
5820
- placeholder: req.placeholder ?? strings.inputOptionalNotePlaceholder,
5821
- onInput: (e) => setNote(e.target.value),
5822
- onKeyDown,
5823
- "data-testid": `${TID.formField}-note`
5824
- }
5825
- )
5826
- ] }) : null,
5827
- /* @__PURE__ */ jsxs13("div", { class: `${p15}-form-actions`, children: [
5828
- /* @__PURE__ */ jsx16("span", { class: `${p15}-form-hint`, children: strings.inputConfirmHint }),
5829
- /* @__PURE__ */ jsx16("button", { type: "button", class: `${p15}-form-skip`, onClick: no, "data-testid": TID.toolInputSkip, children: strings.confirmNo }),
5830
- /* @__PURE__ */ jsx16("button", { type: "button", class: `${p15}-form-submit`, onClick: yes, "data-testid": TID.toolInputSubmit, children: strings.confirmYes })
5831
- ] })
5832
- ] });
5833
- }
5834
- function Section({ label, text }) {
5835
- return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui-section`, children: [
5836
- /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-label`, children: label }),
5837
- /* @__PURE__ */ jsx16("p", { class: `${p15}-toolui-text`, children: text })
5838
- ] });
5732
+ function buildAnswersReason(questions, values) {
5733
+ const answers = questions.flatMap((q) => {
5734
+ const flat = values[q.key];
5735
+ if (flat == null || flat.trim() === "") return [];
5736
+ const value = q.type === "multi-select" ? flat.split(",").map((s) => s.trim()).filter(Boolean) : flat;
5737
+ return [{ key: q.key, value }];
5738
+ });
5739
+ return JSON.stringify({ answers });
5839
5740
  }
5840
5741
  function DecidedCard({
5841
5742
  part,
@@ -5844,31 +5745,44 @@ function DecidedCard({
5844
5745
  editable,
5845
5746
  onEdit
5846
5747
  }) {
5847
- const output = useComputed3(() => part.outputSig.value);
5848
5748
  const approval = useComputed3(() => part.approvalSig.value);
5849
5749
  const skipped = approval.value?.approved === false;
5850
- const answer = approval.value?.approved !== void 0 ? approval.value.reason ?? "" : summarizeOutput(output.value, strings);
5750
+ const answers = approval.value?.approved ? parseAnswers(approval.value.reason) : {};
5851
5751
  return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui`, "data-testid": TID.toolDecision, children: [
5852
5752
  /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui-head`, children: [
5853
5753
  /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-accent`, children: strings.inputBadge }),
5854
5754
  /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge`, children: skipped ? strings.inputSkipped : strings.inputAnswered })
5855
5755
  ] }),
5856
- req.description ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-desc`, children: req.description }) : null,
5857
- /* @__PURE__ */ jsx16(Section, { label: strings.inputQuestion, text: req.question }),
5858
- !skipped && answer ? /* @__PURE__ */ jsx16(Section, { label: strings.inputYourAnswer, text: answer }) : null,
5756
+ req.intro ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-desc`, children: req.intro }) : null,
5757
+ req.questions.map((q) => {
5758
+ const text = skipped ? "" : answers[q.key] ?? "";
5759
+ return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui-section`, children: [
5760
+ /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-label`, children: q.question }),
5761
+ text ? /* @__PURE__ */ jsx16("p", { class: `${p15}-toolui-text`, children: text }) : null
5762
+ ] }, q.key);
5763
+ }),
5859
5764
  editable ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-actions`, children: /* @__PURE__ */ jsx16("button", { type: "button", class: `${p15}-form-skip`, onClick: onEdit, "data-testid": TID.toolEdit, children: strings.edit }) }) : null
5860
5765
  ] });
5861
5766
  }
5862
- function summarizeOutput(output, strings) {
5863
- if (output == null) return "";
5864
- if (typeof output === "string") return output;
5865
- if (typeof output === "object") {
5866
- const rec = output;
5867
- if ("confirmed" in rec) return rec.confirmed ? strings.confirmYes : strings.confirmNo;
5868
- if (typeof rec.responseText === "string" && rec.responseText) return rec.responseText;
5869
- return Object.values(rec).filter((v) => typeof v === "string" || typeof v === "number").join(", ");
5767
+ function parseAnswers(reason) {
5768
+ if (!reason) return {};
5769
+ const parsed = (() => {
5770
+ try {
5771
+ return JSON.parse(reason);
5772
+ } catch {
5773
+ return void 0;
5774
+ }
5775
+ })();
5776
+ const list = parsed?.answers;
5777
+ if (!Array.isArray(list)) return {};
5778
+ const out = {};
5779
+ for (const entry of list) {
5780
+ if (!entry || typeof entry !== "object") continue;
5781
+ const { key, value } = entry;
5782
+ if (typeof key !== "string") continue;
5783
+ out[key] = Array.isArray(value) ? value.filter((v) => typeof v === "string").join(", ") : String(value ?? "");
5870
5784
  }
5871
- return String(output);
5785
+ return out;
5872
5786
  }
5873
5787
 
5874
5788
  // src/ui/tool-call.tsx
@@ -6018,15 +5932,14 @@ function ToolPartView({
6018
5932
  }) {
6019
5933
  const hasApproval = useComputed5(() => part.approvalSig.value !== void 0);
6020
5934
  if (tool?.humanInLoop) {
6021
- if (isAskUserInputTool(part.toolName)) {
5935
+ if (isAskUserQuestionsTool(part.toolName)) {
6022
5936
  return /* @__PURE__ */ jsx18(
6023
- ToolAskInput,
5937
+ ToolAskQuestions,
6024
5938
  {
6025
5939
  part,
6026
5940
  strings,
6027
5941
  active: interactive,
6028
5942
  superseded,
6029
- onSubmit: tool.onResult,
6030
5943
  onDecision: tool.onDecision,
6031
5944
  onEdit: tool.onEdit
6032
5945
  }
@@ -6108,7 +6021,7 @@ function MessageList({
6108
6021
  }) {
6109
6022
  const ref = useRef5(null);
6110
6023
  const messages = useComputed6(() => messagesSig.value);
6111
- const [showJump, setShowJump] = useState7(false);
6024
+ const [showJump, setShowJump] = useState6(false);
6112
6025
  const hasHydratedRef = useRef5(false);
6113
6026
  const detachedRef = useRef5(false);
6114
6027
  const interactingRef = useRef5(false);
@@ -6395,7 +6308,7 @@ function dayLabel(createdAt, strings) {
6395
6308
  }
6396
6309
 
6397
6310
  // src/ui/conversation-list.tsx
6398
- import { useEffect as useEffect8, useState as useState8 } from "preact/hooks";
6311
+ import { useEffect as useEffect8, useState as useState7 } from "preact/hooks";
6399
6312
 
6400
6313
  // src/ui/history-groups.ts
6401
6314
  var HISTORY_BUCKETS = ["today", "yesterday", "lastWeek", "older"];
@@ -6454,8 +6367,8 @@ function ConversationList({
6454
6367
  }) {
6455
6368
  const p36 = BRAND.cssPrefix;
6456
6369
  const seed = transport.peekConversations({ visitorId });
6457
- const [state, setState] = useState8(seed ? "loaded" : "loading");
6458
- const [conversations, setChats] = useState8(seed?.conversations ?? []);
6370
+ const [state, setState] = useState7(seed ? "loaded" : "loading");
6371
+ const [conversations, setChats] = useState7(seed?.conversations ?? []);
6459
6372
  useEffect8(() => {
6460
6373
  let cancelled = false;
6461
6374
  transport.listConversations({ visitorId }).then((res) => {
@@ -7061,7 +6974,7 @@ var chatLayout = {
7061
6974
  };
7062
6975
 
7063
6976
  // src/ui/modules/help.tsx
7064
- import { useEffect as useEffect10, useMemo as useMemo2, useState as useState9 } from "preact/hooks";
6977
+ import { useEffect as useEffect10, useMemo as useMemo2, useState as useState8 } from "preact/hooks";
7065
6978
 
7066
6979
  // src/ui/back-header.tsx
7067
6980
  import { jsx as jsx25, jsxs as jsxs21 } from "preact/jsx-runtime";
@@ -7178,11 +7091,11 @@ function ArticleRow({ article, nav }) {
7178
7091
  }
7179
7092
  function HelpRoot({ transport, strings, config, nav, bus, panelProps }) {
7180
7093
  const tags = config.contentTags;
7181
- const [state, setState] = useState9("loading");
7182
- const [errorMsg, setErrorMsg] = useState9(strings.errorGeneric);
7183
- const [items, setItems] = useState9([]);
7184
- const [query, setQuery] = useState9("");
7185
- const [reloadKey, setReloadKey] = useState9(0);
7094
+ const [state, setState] = useState8("loading");
7095
+ const [errorMsg, setErrorMsg] = useState8(strings.errorGeneric);
7096
+ const [items, setItems] = useState8([]);
7097
+ const [query, setQuery] = useState8("");
7098
+ const [reloadKey, setReloadKey] = useState8(0);
7186
7099
  useEffect10(() => {
7187
7100
  let cancelled = false;
7188
7101
  setState("loading");
@@ -7236,7 +7149,7 @@ var helpLayout = {
7236
7149
  };
7237
7150
 
7238
7151
  // src/ui/modules/home.tsx
7239
- import { useEffect as useEffect11, useState as useState10 } from "preact/hooks";
7152
+ import { useEffect as useEffect11, useState as useState9 } from "preact/hooks";
7240
7153
 
7241
7154
  // src/ui/home-card.tsx
7242
7155
  import { jsx as jsx30 } from "preact/jsx-runtime";
@@ -7264,8 +7177,8 @@ function resolveGreeting(props2) {
7264
7177
  var openContent = (nav, item) => item.url ? nav.push({ kind: "iframe", url: item.url, title: item.title }) : nav.push({ kind: "content", id: item.id, title: item.title });
7265
7178
  function HomeRoot(props2) {
7266
7179
  const { transport, strings, config, nav, bus, panelProps } = props2;
7267
- const [recent, setRecent] = useState10(null);
7268
- const [content, setContent] = useState10([]);
7180
+ const [recent, setRecent] = useState9(null);
7181
+ const [content, setContent] = useState9([]);
7269
7182
  const tagsKey = config.contentTags?.join(",");
7270
7183
  useEffect11(() => {
7271
7184
  if (!config.showRecentConversations) return;
@@ -7355,16 +7268,16 @@ var homeLayout = {
7355
7268
  };
7356
7269
 
7357
7270
  // src/ui/modules/news.tsx
7358
- import { useEffect as useEffect12, useState as useState11 } from "preact/hooks";
7271
+ import { useEffect as useEffect12, useState as useState10 } from "preact/hooks";
7359
7272
  import { jsx as jsx32, jsxs as jsxs27 } from "preact/jsx-runtime";
7360
7273
  var p29 = BRAND.cssPrefix;
7361
7274
  var log15 = logger.scope("news");
7362
7275
  function NewsRoot({ transport, strings, config, nav, bus, panelProps }) {
7363
7276
  const tags = config.contentTags;
7364
- const [state, setState] = useState11("loading");
7365
- const [errorMsg, setErrorMsg] = useState11(strings.errorGeneric);
7366
- const [items, setItems] = useState11([]);
7367
- const [reloadKey, setReloadKey] = useState11(0);
7277
+ const [state, setState] = useState10("loading");
7278
+ const [errorMsg, setErrorMsg] = useState10(strings.errorGeneric);
7279
+ const [items, setItems] = useState10([]);
7280
+ const [reloadKey, setReloadKey] = useState10(0);
7368
7281
  useEffect12(() => {
7369
7282
  let cancelled = false;
7370
7283
  setState("loading");
@@ -7487,15 +7400,15 @@ function IframeView({ url, title, strings, onBack, actions }) {
7487
7400
  }
7488
7401
 
7489
7402
  // src/ui/content-view.tsx
7490
- import { useCallback as useCallback3, useEffect as useEffect13, useState as useState12 } from "preact/hooks";
7403
+ import { useCallback as useCallback3, useEffect as useEffect13, useState as useState11 } from "preact/hooks";
7491
7404
  import { jsx as jsx35, jsxs as jsxs30 } from "preact/jsx-runtime";
7492
7405
  var p32 = BRAND.cssPrefix;
7493
7406
  var log16 = logger.scope("content");
7494
7407
  var READ_DWELL_MS = 5e3;
7495
7408
  function ContentView({ id, title, transport, strings, bus, onBack, actions }) {
7496
- const [item, setItem] = useState12(null);
7497
- const [failed, setFailed] = useState12(false);
7498
- const [reloadKey, setReloadKey] = useState12(0);
7409
+ const [item, setItem] = useState11(null);
7410
+ const [failed, setFailed] = useState11(false);
7411
+ const [reloadKey, setReloadKey] = useState11(0);
7499
7412
  const retry = useCallback3(() => {
7500
7413
  setFailed(false);
7501
7414
  setItem(null);
@@ -7739,11 +7652,11 @@ function ModulesEmpty({ strings, onClose }) {
7739
7652
  }
7740
7653
 
7741
7654
  // src/ui/use-launcher-callout.ts
7742
- import { useCallback as useCallback5, useEffect as useEffect15, useState as useState13 } from "preact/hooks";
7655
+ import { useCallback as useCallback5, useEffect as useEffect15, useState as useState12 } from "preact/hooks";
7743
7656
  function useLauncherCallout({ callout, persistence }) {
7744
7657
  const textKey = callout?.text ?? "";
7745
7658
  const persistent = callout?.persistent ?? true;
7746
- const [dismissed, setDismissed] = useState13(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
7659
+ const [dismissed, setDismissed] = useState12(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
7747
7660
  useEffect15(() => {
7748
7661
  setDismissed(persistent ? false : persistence.loadCalloutDismissed(textKey));
7749
7662
  }, [textKey, persistent, persistence]);
@@ -7772,21 +7685,21 @@ function isAbortError(error) {
7772
7685
  return error instanceof DOMException ? error.name === "AbortError" : error?.name === "AbortError";
7773
7686
  }
7774
7687
  function App({ options, hostElement, bus }) {
7775
- const [persistence] = useState14(
7688
+ const [persistence] = useState13(
7776
7689
  () => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
7777
7690
  );
7778
- const [visitorId, setVisitorId] = useState14(() => persistence.getVisitorId());
7691
+ const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
7779
7692
  const initialSettings = persistence.loadUserPrefs();
7780
- const [activeLocale, setActiveLocale] = useState14(() => initialSettings.locale ?? options.locale);
7781
- const [activeThemeMode, setActiveThemeMode] = useState14(
7693
+ const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
7694
+ const [activeThemeMode, setActiveThemeMode] = useState13(
7782
7695
  () => initialSettings.themeMode ?? options.themeMode
7783
7696
  );
7784
- const [activeTextSize, setActiveTextSize] = useState14(() => initialSettings.textSize ?? options.textSize);
7697
+ const [activeTextSize, setActiveTextSize] = useState13(() => initialSettings.textSize ?? options.textSize);
7785
7698
  const conversationIdSig = useSignal(persistence.loadConversationId());
7786
7699
  const messagesSig = useSignal([]);
7787
7700
  const unreadCountSig = useSignal(0);
7788
- const [loadingMessages, setLoadingMessages] = useState14(false);
7789
- const [formMarkers, setFormMarkers] = useState14([]);
7701
+ const [loadingMessages, setLoadingMessages] = useState13(false);
7702
+ const [formMarkers, setFormMarkers] = useState13([]);
7790
7703
  function landingTab() {
7791
7704
  const list = options.modules.list;
7792
7705
  const ids = new Set(list.map((m) => m.id));
@@ -7805,15 +7718,15 @@ function App({ options, hostElement, bus }) {
7805
7718
  const homeNav = homeNavRef.current;
7806
7719
  const chatTabIdRef = useRef9(void 0);
7807
7720
  chatTabIdRef.current = chatTabId();
7808
- const [conversationReady, setConversationReady] = useState14(false);
7809
- const [remoteForms, setRemoteForms] = useState14(null);
7810
- const [formsReady, setFormsReady] = useState14(false);
7721
+ const [conversationReady, setConversationReady] = useState13(false);
7722
+ const [remoteForms, setRemoteForms] = useState13(null);
7723
+ const [formsReady, setFormsReady] = useState13(false);
7811
7724
  const isInlineLike = options.mode === "standalone" || options.mode === "inline";
7812
7725
  const initialPanelRef = useRef9(
7813
7726
  resolveInitialPanelState(options, currentViewportWidth(), persistence.loadPanelOpen(), persistence.loadPanelSize())
7814
7727
  );
7815
- const [isOpen, setIsOpen] = useState14(initialPanelRef.current.panelOpen);
7816
- const [activated, setActivated] = useState14(initialPanelRef.current.panelOpen);
7728
+ const [isOpen, setIsOpen] = useState13(initialPanelRef.current.panelOpen);
7729
+ const [activated, setActivated] = useState13(initialPanelRef.current.panelOpen);
7817
7730
  const activatedRef = useRef9(activated);
7818
7731
  activatedRef.current = activated;
7819
7732
  const pendingThreadRef = useRef9(false);
@@ -7822,7 +7735,7 @@ function App({ options, hostElement, bus }) {
7822
7735
  if (isOpen) setActivated(true);
7823
7736
  }, [isOpen]);
7824
7737
  const initialPanelApplied = useRef9(false);
7825
- const [launcherLeaving, setLauncherLeaving] = useState14(false);
7738
+ const [launcherLeaving, setLauncherLeaving] = useState13(false);
7826
7739
  const { dismissed: calloutDismissed, dismissCallout: dismissCalloutRaw } = useLauncherCallout({
7827
7740
  callout: options.launcher.callout,
7828
7741
  persistence
@@ -7833,21 +7746,21 @@ function App({ options, hostElement, bus }) {
7833
7746
  bus.emit("calloutDismiss", void 0);
7834
7747
  dismissCalloutRaw();
7835
7748
  }, [bus, dismissCalloutRaw]);
7836
- const [panelSize, setPanelSize] = useState14(initialPanelRef.current.panelSize);
7749
+ const [panelSize, setPanelSize] = useState13(initialPanelRef.current.panelSize);
7837
7750
  const initialSizeApplied = useRef9(false);
7838
- const [view, setView] = useState14("chat");
7839
- const [canSend, setCanSend] = useState14(true);
7840
- const [streaming, setStreaming] = useState14(false);
7841
- const [agent, setAgent] = useState14(null);
7842
- const [suggestions, setSuggestions] = useState14([]);
7843
- const [activeCancel, setActiveCancel] = useState14(null);
7844
- const [activeDetach, setActiveDetach] = useState14(null);
7751
+ const [view, setView] = useState13("chat");
7752
+ const [canSend, setCanSend] = useState13(true);
7753
+ const [streaming, setStreaming] = useState13(false);
7754
+ const [agent, setAgent] = useState13(null);
7755
+ const [suggestions, setSuggestions] = useState13([]);
7756
+ const [activeCancel, setActiveCancel] = useState13(null);
7757
+ const [activeDetach, setActiveDetach] = useState13(null);
7845
7758
  const stringsRef = useRef9(options.strings);
7846
- const [parsedSite, setParsedSite] = useState14(void 0);
7847
- const [parsedBlocks, setParsedBlocks] = useState14(void 0);
7848
- const [sidebarCollapsed, setSidebarCollapsed] = useState14(() => persistence.loadSidebarCollapsed() ?? false);
7849
- const [formContext, setFormContext] = useState14({});
7850
- const [transport] = useState14(
7759
+ const [parsedSite, setParsedSite] = useState13(void 0);
7760
+ const [parsedBlocks, setParsedBlocks] = useState13(void 0);
7761
+ const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
7762
+ const [formContext, setFormContext] = useState13({});
7763
+ const [transport] = useState13(
7851
7764
  () => new AgentTransport({
7852
7765
  agentApiBaseUrl: options.agentApiBaseUrl,
7853
7766
  dataApiBaseUrl: options.dataApiBaseUrl,
@@ -7859,8 +7772,8 @@ function App({ options, hostElement, bus }) {
7859
7772
  endpoints: options.endpoints
7860
7773
  })
7861
7774
  );
7862
- const [reducer] = useState14(() => new StreamReducer(messagesSig));
7863
- const [feedback] = useState14(() => new FeedbackBus(options.sound, options.haptics));
7775
+ const [reducer] = useState13(() => new StreamReducer(messagesSig));
7776
+ const [feedback] = useState13(() => new FeedbackBus(options.sound, options.haptics));
7864
7777
  const patchAndSync = useCallback6(
7865
7778
  (patch) => {
7866
7779
  persistence.patchUserPrefs(patch);