@helpai/elements 0.53.0 → 0.54.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/web-component.mjs CHANGED
@@ -112,7 +112,7 @@ var STRINGS_EN = {
112
112
  newsLoading: "Loading news\u2026",
113
113
  newsBack: "Back to news",
114
114
  newsPublishedAt: "Published {date}",
115
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
115
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
116
116
  formSubmit: "Submit",
117
117
  formSkip: "Maybe later",
118
118
  formSubmitted: "Completed",
@@ -132,26 +132,15 @@ var STRINGS_EN = {
132
132
  formChooseAtMost: "Choose at most {max}",
133
133
  formOther: "Other",
134
134
  formOtherPlaceholder: "Type your answer\u2026",
135
- inputRequired: "User Input Required",
136
- inputBadge: "User Input",
135
+ inputRequired: "Questions for you",
136
+ inputBadge: "Questions",
137
137
  inputAnswered: "Answered",
138
138
  inputSkipped: "Skipped",
139
- inputQuestion: "Question",
140
- inputYourAnswer: "Your answer",
141
- inputSubmit: "Submit answer",
139
+ inputSubmit: "Submit answers",
142
140
  inputSubmitHint: "Enter to send \xB7 Shift+Enter = new line",
143
- inputAnswerPlaceholder: "Type your answer\u2026",
144
141
  inputSkip: "Skip",
145
142
  confirmYes: "Yes",
146
143
  confirmNo: "No",
147
- inputConfirmHint: "Choose yes or no.",
148
- inputOptionalNote: "Optional note",
149
- inputOptionalNotePlaceholder: "Optional comment\u2026",
150
- inputSubmitted: "Answer submitted",
151
- respFreeText: "Free Text",
152
- respSingleChoice: "Single Choice",
153
- respMultiChoice: "Multiple Choice",
154
- respConfirmation: "Confirmation",
155
144
  approvalRequired: "Approval required",
156
145
  approve: "Approve",
157
146
  reject: "Reject",
@@ -256,7 +245,7 @@ var STRINGS_FR = {
256
245
  newsLoading: "Chargement des actualit\xE9s\u2026",
257
246
  newsBack: "Retour aux actualit\xE9s",
258
247
  newsPublishedAt: "Publi\xE9 le {date}",
259
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
248
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
260
249
  formSubmit: "Envoyer",
261
250
  formSkip: "Plus tard",
262
251
  formSubmitted: "Termin\xE9",
@@ -276,26 +265,15 @@ var STRINGS_FR = {
276
265
  formChooseAtMost: "Choisissez au plus {max}",
277
266
  formOther: "Autre",
278
267
  formOtherPlaceholder: "Saisissez votre r\xE9ponse\u2026",
279
- inputRequired: "Saisie requise",
280
- inputBadge: "Saisie",
268
+ inputRequired: "Questions pour vous",
269
+ inputBadge: "Questions",
281
270
  inputAnswered: "R\xE9pondu",
282
271
  inputSkipped: "Ignor\xE9",
283
- inputQuestion: "Question",
284
- inputYourAnswer: "Votre r\xE9ponse",
285
- inputSubmit: "Envoyer la r\xE9ponse",
272
+ inputSubmit: "Envoyer les r\xE9ponses",
286
273
  inputSubmitHint: "Entr\xE9e pour envoyer \xB7 Maj+Entr\xE9e = saut de ligne",
287
- inputAnswerPlaceholder: "Saisissez votre r\xE9ponse\u2026",
288
274
  inputSkip: "Ignorer",
289
275
  confirmYes: "Oui",
290
276
  confirmNo: "Non",
291
- inputConfirmHint: "Choisissez oui ou non.",
292
- inputOptionalNote: "Note facultative",
293
- inputOptionalNotePlaceholder: "Commentaire facultatif\u2026",
294
- inputSubmitted: "R\xE9ponse envoy\xE9e",
295
- respFreeText: "Texte libre",
296
- respSingleChoice: "Choix unique",
297
- respMultiChoice: "Choix multiple",
298
- respConfirmation: "Confirmation",
299
277
  approvalRequired: "Approbation requise",
300
278
  approve: "Approuver",
301
279
  reject: "Refuser",
@@ -400,7 +378,7 @@ var STRINGS_AR = {
400
378
  newsLoading: "\u062C\u0627\u0631\u064D \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0623\u062E\u0628\u0627\u0631\u2026",
401
379
  newsBack: "\u0627\u0644\u0639\u0648\u062F\u0629 \u0625\u0644\u0649 \u0627\u0644\u0623\u062E\u0628\u0627\u0631",
402
380
  newsPublishedAt: "\u0646\u064F\u0634\u0631 \u0641\u064A {date}",
403
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
381
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
404
382
  formSubmit: "\u0625\u0631\u0633\u0627\u0644",
405
383
  formSkip: "\u0644\u0627\u062D\u0642\u064B\u0627",
406
384
  formSubmitted: "\u062A\u0645",
@@ -420,26 +398,15 @@ var STRINGS_AR = {
420
398
  formChooseAtMost: "\u0627\u062E\u062A\u0631 {max} \u0639\u0644\u0649 \u0627\u0644\u0623\u0643\u062B\u0631",
421
399
  formOther: "\u0623\u062E\u0631\u0649",
422
400
  formOtherPlaceholder: "\u0627\u0643\u062A\u0628 \u0625\u062C\u0627\u0628\u062A\u0643\u2026",
423
- inputRequired: "\u0645\u0637\u0644\u0648\u0628 \u0625\u062F\u062E\u0627\u0644 \u0645\u0646 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645",
424
- inputBadge: "\u0625\u062F\u062E\u0627\u0644 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645",
401
+ inputRequired: "\u0623\u0633\u0626\u0644\u0629 \u0644\u0643",
402
+ inputBadge: "\u0623\u0633\u0626\u0644\u0629",
425
403
  inputAnswered: "\u062A\u0645\u062A \u0627\u0644\u0625\u062C\u0627\u0628\u0629",
426
404
  inputSkipped: "\u062A\u0645 \u0627\u0644\u062A\u062E\u0637\u064A",
427
- inputQuestion: "\u0627\u0644\u0633\u0624\u0627\u0644",
428
- inputYourAnswer: "\u0625\u062C\u0627\u0628\u062A\u0643",
429
- inputSubmit: "\u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0625\u062C\u0627\u0628\u0629",
405
+ inputSubmit: "\u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0625\u062C\u0627\u0628\u0627\u062A",
430
406
  inputSubmitHint: "Enter \u0644\u0644\u0625\u0631\u0633\u0627\u0644 \xB7 Shift+Enter = \u0633\u0637\u0631 \u062C\u062F\u064A\u062F",
431
- inputAnswerPlaceholder: "\u0627\u0643\u062A\u0628 \u0625\u062C\u0627\u0628\u062A\u0643\u2026",
432
407
  inputSkip: "\u062A\u062E\u0637\u064D\u0651",
433
408
  confirmYes: "\u0646\u0639\u0645",
434
409
  confirmNo: "\u0644\u0627",
435
- inputConfirmHint: "\u0627\u062E\u062A\u0631 \u0646\u0639\u0645 \u0623\u0648 \u0644\u0627.",
436
- inputOptionalNote: "\u0645\u0644\u0627\u062D\u0638\u0629 \u0627\u062E\u062A\u064A\u0627\u0631\u064A\u0629",
437
- inputOptionalNotePlaceholder: "\u062A\u0639\u0644\u064A\u0642 \u0627\u062E\u062A\u064A\u0627\u0631\u064A\u2026",
438
- inputSubmitted: "\u062A\u0645 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0625\u062C\u0627\u0628\u0629",
439
- respFreeText: "\u0646\u0635 \u062D\u0631",
440
- respSingleChoice: "\u0627\u062E\u062A\u064A\u0627\u0631 \u0648\u0627\u062D\u062F",
441
- respMultiChoice: "\u0627\u062E\u062A\u064A\u0627\u0631 \u0645\u062A\u0639\u062F\u062F",
442
- respConfirmation: "\u062A\u0623\u0643\u064A\u062F",
443
410
  approvalRequired: "\u0645\u0637\u0644\u0648\u0628 \u0645\u0648\u0627\u0641\u0642\u0629",
444
411
  approve: "\u0645\u0648\u0627\u0641\u0642\u0629",
445
412
  reject: "\u0631\u0641\u0636",
@@ -544,7 +511,7 @@ var STRINGS_ES = {
544
511
  newsLoading: "Cargando novedades\u2026",
545
512
  newsBack: "Volver a novedades",
546
513
  newsPublishedAt: "Publicado el {date}",
547
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
514
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
548
515
  formSubmit: "Enviar",
549
516
  formSkip: "Quiz\xE1 m\xE1s tarde",
550
517
  formSubmitted: "Completado",
@@ -564,26 +531,15 @@ var STRINGS_ES = {
564
531
  formChooseAtMost: "Elige como m\xE1ximo {max}",
565
532
  formOther: "Otro",
566
533
  formOtherPlaceholder: "Escribe tu respuesta\u2026",
567
- inputRequired: "Entrada requerida",
568
- inputBadge: "Entrada",
534
+ inputRequired: "Preguntas para ti",
535
+ inputBadge: "Preguntas",
569
536
  inputAnswered: "Respondido",
570
537
  inputSkipped: "Omitido",
571
- inputQuestion: "Pregunta",
572
- inputYourAnswer: "Tu respuesta",
573
- inputSubmit: "Enviar respuesta",
538
+ inputSubmit: "Enviar respuestas",
574
539
  inputSubmitHint: "Enter para enviar \xB7 May\xFAs+Enter = nueva l\xEDnea",
575
- inputAnswerPlaceholder: "Escribe tu respuesta\u2026",
576
540
  inputSkip: "Omitir",
577
541
  confirmYes: "S\xED",
578
542
  confirmNo: "No",
579
- inputConfirmHint: "Elige s\xED o no.",
580
- inputOptionalNote: "Nota opcional",
581
- inputOptionalNotePlaceholder: "Comentario opcional\u2026",
582
- inputSubmitted: "Respuesta enviada",
583
- respFreeText: "Texto libre",
584
- respSingleChoice: "Opci\xF3n \xFAnica",
585
- respMultiChoice: "Opci\xF3n m\xFAltiple",
586
- respConfirmation: "Confirmaci\xF3n",
587
543
  approvalRequired: "Aprobaci\xF3n requerida",
588
544
  approve: "Aprobar",
589
545
  reject: "Rechazar",
@@ -688,7 +644,7 @@ var STRINGS_HE = {
688
644
  newsLoading: "\u05D8\u05D5\u05E2\u05DF \u05D7\u05D3\u05E9\u05D5\u05EA\u2026",
689
645
  newsBack: "\u05D7\u05D6\u05E8\u05D4 \u05DC\u05D7\u05D3\u05E9\u05D5\u05EA",
690
646
  newsPublishedAt: "\u05E4\u05D5\u05E8\u05E1\u05DD \u05D1-{date}",
691
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ────
647
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ────
692
648
  formSubmit: "\u05E9\u05DC\u05D9\u05D7\u05D4",
693
649
  formSkip: "\u05D0\u05D7\u05E8 \u05DB\u05DA",
694
650
  formSubmitted: "\u05E0\u05E9\u05DC\u05D7",
@@ -708,26 +664,15 @@ var STRINGS_HE = {
708
664
  formChooseAtMost: "\u05D1\u05D7\u05E8 \u05DC\u05DB\u05DC \u05D4\u05D9\u05D5\u05EA\u05E8 {max}",
709
665
  formOther: "\u05D0\u05D7\u05E8",
710
666
  formOtherPlaceholder: "\u05DB\u05EA\u05D5\u05D1 \u05D0\u05EA \u05EA\u05E9\u05D5\u05D1\u05EA\u05DA\u2026",
711
- inputRequired: "\u05E0\u05D3\u05E8\u05E9 \u05E7\u05DC\u05D8 \u05DE\u05D4\u05DE\u05E9\u05EA\u05DE\u05E9",
712
- inputBadge: "\u05E7\u05DC\u05D8 \u05DE\u05E9\u05EA\u05DE\u05E9",
667
+ inputRequired: "\u05E9\u05D0\u05DC\u05D5\u05EA \u05E2\u05D1\u05D5\u05E8\u05DA",
668
+ inputBadge: "\u05E9\u05D0\u05DC\u05D5\u05EA",
713
669
  inputAnswered: "\u05E0\u05E2\u05E0\u05D4",
714
670
  inputSkipped: "\u05D3\u05D5\u05DC\u05D2",
715
- inputQuestion: "\u05E9\u05D0\u05DC\u05D4",
716
- inputYourAnswer: "\u05D4\u05EA\u05E9\u05D5\u05D1\u05D4 \u05E9\u05DC\u05DA",
717
- inputSubmit: "\u05E9\u05DC\u05D9\u05D7\u05EA \u05EA\u05E9\u05D5\u05D1\u05D4",
671
+ inputSubmit: "\u05E9\u05DC\u05D9\u05D7\u05EA \u05EA\u05E9\u05D5\u05D1\u05D5\u05EA",
718
672
  inputSubmitHint: "Enter \u05DC\u05E9\u05DC\u05D9\u05D7\u05D4 \xB7 Shift+Enter = \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
719
- inputAnswerPlaceholder: "\u05DB\u05EA\u05D5\u05D1 \u05D0\u05EA \u05EA\u05E9\u05D5\u05D1\u05EA\u05DA\u2026",
720
673
  inputSkip: "\u05D3\u05D9\u05DC\u05D5\u05D2",
721
674
  confirmYes: "\u05DB\u05DF",
722
675
  confirmNo: "\u05DC\u05D0",
723
- inputConfirmHint: "\u05D1\u05D7\u05E8 \u05DB\u05DF \u05D0\u05D5 \u05DC\u05D0.",
724
- inputOptionalNote: "\u05D4\u05E2\u05E8\u05D4 \u05D0\u05D5\u05E4\u05E6\u05D9\u05D5\u05E0\u05DC\u05D9\u05EA",
725
- inputOptionalNotePlaceholder: "\u05D4\u05E2\u05E8\u05D4 \u05D0\u05D5\u05E4\u05E6\u05D9\u05D5\u05E0\u05DC\u05D9\u05EA\u2026",
726
- inputSubmitted: "\u05D4\u05EA\u05E9\u05D5\u05D1\u05D4 \u05E0\u05E9\u05DC\u05D7\u05D4",
727
- respFreeText: "\u05D8\u05E7\u05E1\u05D8 \u05D7\u05D5\u05E4\u05E9\u05D9",
728
- respSingleChoice: "\u05D1\u05D7\u05D9\u05E8\u05D4 \u05D9\u05D7\u05D9\u05D3\u05D4",
729
- respMultiChoice: "\u05D1\u05D7\u05D9\u05E8\u05D4 \u05DE\u05E8\u05D5\u05D1\u05D4",
730
- respConfirmation: "\u05D0\u05D9\u05E9\u05D5\u05E8",
731
676
  approvalRequired: "\u05E0\u05D3\u05E8\u05E9 \u05D0\u05D9\u05E9\u05D5\u05E8",
732
677
  approve: "\u05D0\u05D9\u05E9\u05D5\u05E8",
733
678
  reject: "\u05D3\u05D7\u05D9\u05D9\u05D4",
@@ -1850,7 +1795,7 @@ function applyHostAttributes(host, resolved) {
1850
1795
  import { h, render as renderPreact } from "preact";
1851
1796
 
1852
1797
  // src/ui/app.tsx
1853
- import { useCallback as useCallback6, useEffect as useEffect16, useLayoutEffect as useLayoutEffect3, useMemo as useMemo3, useRef as useRef9, useState as useState14 } from "preact/hooks";
1798
+ import { useCallback as useCallback6, useEffect as useEffect16, useLayoutEffect as useLayoutEffect3, useMemo as useMemo3, useRef as useRef9, useState as useState13 } from "preact/hooks";
1854
1799
  import { batch, useComputed as useComputed8, useSignal } from "@preact/signals";
1855
1800
 
1856
1801
  // src/core/handshake-shape.ts
@@ -1935,7 +1880,7 @@ function createAuth(opts) {
1935
1880
  }
1936
1881
 
1937
1882
  // src/core/version.ts
1938
- var ELEMENTS_VERSION = true ? "0.53.0" : "0.0.0-dev";
1883
+ var ELEMENTS_VERSION = true ? "0.54.1" : "0.0.0-dev";
1939
1884
  var ELEMENTS_VERSION_PARAM = "_ev";
1940
1885
 
1941
1886
  // src/stream/types.ts
@@ -3778,7 +3723,7 @@ var TID = {
3778
3723
  helpArticle: `${p2}-help-article`,
3779
3724
  /** News list item — suffix `-{id}`. */
3780
3725
  newsItem: `${p2}-news-item`,
3781
- // ── Forms + human-in-the-loop (forms / ask-input / approval) ─────
3726
+ // ── Forms + human-in-the-loop (forms / ask-questions / approval) ─────
3782
3727
  /** Form gate root — a timeline row that locks the chat while open. */
3783
3728
  formGate: `${p2}-form-gate`,
3784
3729
  /** "Form submitted / skipped" marker row (wire-reconstructed on resume). */
@@ -3795,11 +3740,11 @@ var TID = {
3795
3740
  formSkip: `${p2}-form-skip`,
3796
3741
  /** A single form field control — suffix `-{name}` at the JSX site. */
3797
3742
  formField: `${p2}-form-field`,
3798
- /** Ask-input tool root (inline form in a message bubble). */
3799
- toolAskInput: `${p2}-tool-ask-input`,
3800
- /** Ask-input submit button. */
3743
+ /** Ask-questions tool root (inline form in a message bubble). */
3744
+ toolAskQuestions: `${p2}-tool-ask-questions`,
3745
+ /** Ask-questions submit button. */
3801
3746
  toolInputSubmit: `${p2}-tool-input-submit`,
3802
- /** Ask-input skip button. */
3747
+ /** Ask-questions skip/cancel button. */
3803
3748
  toolInputSkip: `${p2}-tool-input-skip`,
3804
3749
  /** Tool-approval root (approve/reject prompt). */
3805
3750
  toolApproval: `${p2}-tool-approval`,
@@ -4006,7 +3951,7 @@ var KEEP_VISIBLE = 56;
4006
3951
  function useDragMove(panelEl, enabled) {
4007
3952
  useEffect3(() => {
4008
3953
  if (!enabled || !panelEl) return;
4009
- const num2 = (v) => Number.parseFloat(v) || 0;
3954
+ const num = (v) => Number.parseFloat(v) || 0;
4010
3955
  const clamp = (v, max) => Math.min(max, Math.max(-max, v));
4011
3956
  let drag = null;
4012
3957
  const onDown = (e) => {
@@ -4017,8 +3962,8 @@ function useDragMove(panelEl, enabled) {
4017
3962
  id: e.pointerId,
4018
3963
  x: e.clientX,
4019
3964
  y: e.clientY,
4020
- dx: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
4021
- dy: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
3965
+ dx: num(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
3966
+ dy: num(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
4022
3967
  // Centred origin: |offset| ≤ (viewport + panel)/2 − keepVisible keeps a
4023
3968
  // strip of the dialog reachable so it can never be lost off-screen.
4024
3969
  maxX: (window.innerWidth + rect.width) / 2 - KEEP_VISIBLE,
@@ -4951,7 +4896,7 @@ function HeaderActions({ panelProps, variant }) {
4951
4896
  }
4952
4897
 
4953
4898
  // src/ui/message-list.tsx
4954
- import { useEffect as useEffect7, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState7 } from "preact/hooks";
4899
+ import { useEffect as useEffect7, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState6 } from "preact/hooks";
4955
4900
  import { useComputed as useComputed6 } from "@preact/signals";
4956
4901
 
4957
4902
  // src/ui/form/dynamic-form.tsx
@@ -5351,10 +5296,10 @@ function FormDoneMarker({
5351
5296
  import { useComputed as useComputed5 } from "@preact/signals";
5352
5297
 
5353
5298
  // src/stream/constants.ts
5354
- function isAskUserInputTool(toolName2) {
5299
+ function isAskUserQuestionsTool(toolName2) {
5355
5300
  if (!toolName2) return false;
5356
5301
  const name = toolName2.startsWith("tool:") ? toolName2.slice(5) : toolName2;
5357
- return name === "ask-user-input" || name === "ask_user_input" || name === "request-user-input" || name === "request_user_input";
5302
+ return name === "ask-user-questions" || name === "ask_user_questions";
5358
5303
  }
5359
5304
 
5360
5305
  // src/ui/markdown.tsx
@@ -5621,107 +5566,103 @@ function ToolApproval({ part, strings, active, superseded = false, onDecision, o
5621
5566
  ] });
5622
5567
  }
5623
5568
 
5624
- // src/ui/tool-ask-input.tsx
5569
+ // src/ui/tool-ask-questions.tsx
5625
5570
  import { useComputed as useComputed3 } from "@preact/signals";
5626
- import { useState as useState6 } from "preact/hooks";
5627
5571
 
5628
5572
  // src/ui/form/field.ts
5629
- function parseAskUserInput(input) {
5573
+ var QUESTION_TYPES = /* @__PURE__ */ new Set([
5574
+ "text",
5575
+ "email",
5576
+ "phone",
5577
+ "number",
5578
+ "date",
5579
+ "single-select",
5580
+ "multi-select",
5581
+ "boolean"
5582
+ ]);
5583
+ function parseAskUserQuestions(input) {
5630
5584
  const raw = input && typeof input === "object" ? input : {};
5631
- const responseType = raw.responseType;
5585
+ const rawQuestions = Array.isArray(raw.questions) ? raw.questions : [];
5586
+ const questions = rawQuestions.map(parseQuestion).filter((q) => q !== null);
5587
+ return { intro: str(raw.intro), questions };
5588
+ }
5589
+ function parseQuestion(value, index) {
5590
+ if (!value || typeof value !== "object") return null;
5591
+ const raw = value;
5592
+ const type = QUESTION_TYPES.has(raw.type) ? raw.type : "text";
5632
5593
  return {
5633
- title: str(raw.title),
5594
+ key: str(raw.key) ?? `q${index + 1}`,
5634
5595
  question: str(raw.question) ?? "Please provide the missing information.",
5635
- description: str(raw.description),
5636
- placeholder: str(raw.placeholder),
5637
- responseType: responseType === "single-choice" || responseType === "multi-choice" || responseType === "confirmation" || responseType === "free-text" ? responseType : "free-text",
5638
- choices: Array.isArray(raw.choices) ? raw.choices : void 0,
5639
- allowOther: typeof raw.allowOther === "boolean" ? raw.allowOther : void 0,
5640
- required: typeof raw.required === "boolean" ? raw.required : true,
5641
- defaultValues: Array.isArray(raw.defaultValues) ? raw.defaultValues.filter((v) => typeof v === "string") : void 0,
5642
- minSelections: num(raw.minSelections),
5643
- maxSelections: num(raw.maxSelections),
5644
- validationHint: str(raw.validationHint)
5596
+ type,
5597
+ options: Array.isArray(raw.options) ? raw.options.filter((o) => typeof o === "string" && o.trim().length > 0) : void 0,
5598
+ required: typeof raw.required === "boolean" ? raw.required : void 0,
5599
+ helpText: str(raw.helpText)
5645
5600
  };
5646
5601
  }
5647
- function askInputToFields(req) {
5648
- if (req.responseType === "confirmation") return [];
5649
- const options = (req.choices ?? []).map(normalizeChoice).filter((c) => c !== null);
5650
- let type = "textarea";
5651
- if (req.responseType === "single-choice" && options.length > 0) type = "radio";
5652
- else if (req.responseType === "multi-choice") type = "multiselect";
5653
- const defaultValue = type === "multiselect" ? req.defaultValues?.join(", ") : req.defaultValues?.[0];
5654
- return [
5655
- {
5656
- name: "answer",
5657
- label: req.question,
5602
+ function fieldTypeFor(type) {
5603
+ switch (type) {
5604
+ case "text":
5605
+ return "textarea";
5606
+ case "phone":
5607
+ return "tel";
5608
+ case "single-select":
5609
+ case "boolean":
5610
+ return "radio";
5611
+ case "multi-select":
5612
+ return "multiselect";
5613
+ default:
5614
+ return type;
5615
+ }
5616
+ }
5617
+ function askQuestionsToFields(req, yesLabel, noLabel) {
5618
+ return req.questions.map((q) => {
5619
+ const type = fieldTypeFor(q.type);
5620
+ const options = q.type === "boolean" ? [
5621
+ { value: "yes", label: yesLabel },
5622
+ { value: "no", label: noLabel }
5623
+ ] : (q.options ?? []).map((o) => ({ value: o, label: o }));
5624
+ return {
5625
+ name: q.key,
5626
+ label: q.question,
5658
5627
  type,
5659
- placeholder: req.placeholder,
5660
- required: req.required ?? true,
5661
- defaultValue,
5628
+ required: q.required ?? false,
5662
5629
  options: options.length > 0 ? options : void 0,
5663
- allowOther: req.allowOther,
5664
- validationHint: req.validationHint,
5665
- validation: type === "multiselect" ? { minSelections: req.minSelections, maxSelections: req.maxSelections } : void 0
5666
- }
5667
- ];
5668
- }
5669
- function normalizeChoice(c) {
5670
- if (typeof c === "string") return c ? { value: c, label: c } : null;
5671
- if (c && typeof c.value === "string" && c.value)
5672
- return { value: c.value, label: c.label ?? c.value, description: c.description };
5673
- return null;
5630
+ validationHint: q.helpText
5631
+ };
5632
+ });
5674
5633
  }
5675
5634
  function str(v) {
5676
5635
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
5677
5636
  }
5678
- function num(v) {
5679
- return typeof v === "number" && Number.isFinite(v) ? v : void 0;
5680
- }
5681
5637
 
5682
- // src/ui/tool-ask-input.tsx
5638
+ // src/ui/tool-ask-questions.tsx
5683
5639
  import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs13 } from "preact/jsx-runtime";
5684
5640
  var p15 = BRAND.cssPrefix;
5685
- function responseTypeLabel(req, s) {
5686
- switch (req.responseType) {
5687
- case "single-choice":
5688
- return s.respSingleChoice;
5689
- case "multi-choice":
5690
- return s.respMultiChoice;
5691
- case "confirmation":
5692
- return s.respConfirmation;
5693
- default:
5694
- return s.respFreeText;
5695
- }
5696
- }
5697
- function ToolAskInput({ part, strings, active, superseded = false, onSubmit, onDecision, onEdit }) {
5641
+ function ToolAskQuestions({ part, strings, active, superseded = false, onDecision, onEdit }) {
5698
5642
  const state = useComputed3(() => part.stateSig.value);
5699
5643
  const approval = useComputed3(() => part.approvalSig.value);
5700
- const request = useComputed3(() => parseAskUserInput(part.inputSig.value));
5644
+ const request = useComputed3(() => parseAskUserQuestions(part.inputSig.value));
5701
5645
  const { terminal, responded, decided } = toolDecisionState(state.value, approval.value);
5702
- const viaApproval = approval.value !== void 0;
5703
- const resolve = (answer, accepted) => {
5704
- if (viaApproval) onDecision(part.toolCallId, accepted, answer);
5705
- else if (request.value.responseType === "confirmation") onSubmit(part.toolCallId, { confirmed: accepted });
5706
- else onSubmit(part.toolCallId, accepted ? { answer } : {});
5707
- };
5708
5646
  const req = request.value;
5709
5647
  if (decided) {
5710
5648
  const editable = responded && active && !terminal;
5711
5649
  return /* @__PURE__ */ jsx16(DecidedCard, { part, strings, req, editable, onEdit: () => onEdit(part.toolCallId) });
5712
5650
  }
5713
5651
  const stale = superseded;
5714
- return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui${stale ? ` ${p15}-toolui-stale` : ""}`, "data-testid": TID.toolAskInput, children: [
5652
+ return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui${stale ? ` ${p15}-toolui-stale` : ""}`, "data-testid": TID.toolAskQuestions, children: [
5715
5653
  /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-head`, children: stale ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
5716
5654
  /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-accent`, children: strings.inputBadge }),
5717
5655
  /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-muted`, children: strings.statusSuperseded })
5718
- ] }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
5719
- /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-accent`, children: strings.inputRequired }),
5720
- /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge`, children: responseTypeLabel(req, strings) })
5721
- ] }) }),
5722
- req.description ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-desc`, children: req.description }) : null,
5723
- /* @__PURE__ */ jsx16(Section, { label: strings.inputQuestion, text: req.question }),
5724
- stale ? null : /* @__PURE__ */ jsx16(AskBody, { req, strings, resolve })
5656
+ ] }) : /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-accent`, children: strings.inputRequired }) }),
5657
+ req.intro ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-desc`, children: req.intro }) : null,
5658
+ stale ? null : /* @__PURE__ */ jsx16(
5659
+ AskBody,
5660
+ {
5661
+ req,
5662
+ strings,
5663
+ resolve: (reason, accepted) => onDecision(part.toolCallId, accepted, reason)
5664
+ }
5665
+ )
5725
5666
  ] });
5726
5667
  }
5727
5668
  function AskBody({
@@ -5729,72 +5670,32 @@ function AskBody({
5729
5670
  strings,
5730
5671
  resolve
5731
5672
  }) {
5732
- if (req.responseType === "confirmation") {
5733
- return /* @__PURE__ */ jsx16(ConfirmBody, { req, strings, resolve });
5734
- }
5735
- const fields = askInputToFields(req).map((f) => {
5736
- f.label = strings.inputYourAnswer;
5737
- f.placeholder = f.placeholder ?? strings.inputAnswerPlaceholder;
5738
- return f;
5739
- });
5673
+ const fields = askQuestionsToFields(req, strings.confirmYes, strings.confirmNo);
5674
+ const loneTextarea = req.questions.length === 1 && req.questions[0]?.type === "text";
5740
5675
  return /* @__PURE__ */ jsx16(
5741
5676
  DynamicForm,
5742
5677
  {
5743
5678
  fields,
5744
5679
  strings,
5745
5680
  submitLabel: strings.inputSubmit,
5746
- footerHint: req.responseType === "free-text" ? strings.inputSubmitHint : void 0,
5747
- onSubmit: (values) => resolve(values.answer ?? Object.values(values).join(", "), true),
5681
+ footerHint: loneTextarea ? strings.inputSubmitHint : void 0,
5682
+ onSubmit: (values) => resolve(buildAnswersReason(req.questions, values), true),
5748
5683
  skipLabel: strings.inputSkip,
5749
5684
  onSkip: () => resolve(void 0, false),
5750
- submitOnEnter: true,
5685
+ submitOnEnter: loneTextarea,
5751
5686
  submitTestId: TID.toolInputSubmit,
5752
5687
  skipTestId: TID.toolInputSkip
5753
5688
  }
5754
5689
  );
5755
5690
  }
5756
- function ConfirmBody({
5757
- req,
5758
- strings,
5759
- resolve
5760
- }) {
5761
- const [note, setNote] = useState6("");
5762
- const supportsNote = req.allowOther ?? true;
5763
- const yes = () => resolve(note.trim() || void 0, true);
5764
- const no = () => resolve(void 0, false);
5765
- const onKeyDown = (e) => {
5766
- if (e.key !== "Enter" || e.shiftKey || e.isComposing) return;
5767
- e.preventDefault();
5768
- yes();
5769
- };
5770
- return /* @__PURE__ */ jsxs13(Fragment4, { children: [
5771
- supportsNote ? /* @__PURE__ */ jsxs13("label", { class: `${p15}-field`, children: [
5772
- /* @__PURE__ */ jsx16("span", { class: `${p15}-field-label`, children: strings.inputOptionalNote }),
5773
- /* @__PURE__ */ jsx16(
5774
- "textarea",
5775
- {
5776
- class: `${p15}-field-input`,
5777
- rows: 2,
5778
- value: note,
5779
- placeholder: req.placeholder ?? strings.inputOptionalNotePlaceholder,
5780
- onInput: (e) => setNote(e.target.value),
5781
- onKeyDown,
5782
- "data-testid": `${TID.formField}-note`
5783
- }
5784
- )
5785
- ] }) : null,
5786
- /* @__PURE__ */ jsxs13("div", { class: `${p15}-form-actions`, children: [
5787
- /* @__PURE__ */ jsx16("span", { class: `${p15}-form-hint`, children: strings.inputConfirmHint }),
5788
- /* @__PURE__ */ jsx16("button", { type: "button", class: `${p15}-form-skip`, onClick: no, "data-testid": TID.toolInputSkip, children: strings.confirmNo }),
5789
- /* @__PURE__ */ jsx16("button", { type: "button", class: `${p15}-form-submit`, onClick: yes, "data-testid": TID.toolInputSubmit, children: strings.confirmYes })
5790
- ] })
5791
- ] });
5792
- }
5793
- function Section({ label, text }) {
5794
- return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui-section`, children: [
5795
- /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-label`, children: label }),
5796
- /* @__PURE__ */ jsx16("p", { class: `${p15}-toolui-text`, children: text })
5797
- ] });
5691
+ function buildAnswersReason(questions, values) {
5692
+ const answers = questions.flatMap((q) => {
5693
+ const flat = values[q.key];
5694
+ if (flat == null || flat.trim() === "") return [];
5695
+ const value = q.type === "multi-select" ? flat.split(",").map((s) => s.trim()).filter(Boolean) : flat;
5696
+ return [{ key: q.key, value }];
5697
+ });
5698
+ return JSON.stringify({ answers });
5798
5699
  }
5799
5700
  function DecidedCard({
5800
5701
  part,
@@ -5803,31 +5704,44 @@ function DecidedCard({
5803
5704
  editable,
5804
5705
  onEdit
5805
5706
  }) {
5806
- const output = useComputed3(() => part.outputSig.value);
5807
5707
  const approval = useComputed3(() => part.approvalSig.value);
5808
5708
  const skipped = approval.value?.approved === false;
5809
- const answer = approval.value?.approved !== void 0 ? approval.value.reason ?? "" : summarizeOutput(output.value, strings);
5709
+ const answers = approval.value?.approved ? parseAnswers(approval.value.reason) : {};
5810
5710
  return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui`, "data-testid": TID.toolDecision, children: [
5811
5711
  /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui-head`, children: [
5812
5712
  /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge ${p15}-toolui-badge-accent`, children: strings.inputBadge }),
5813
5713
  /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-badge`, children: skipped ? strings.inputSkipped : strings.inputAnswered })
5814
5714
  ] }),
5815
- req.description ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-desc`, children: req.description }) : null,
5816
- /* @__PURE__ */ jsx16(Section, { label: strings.inputQuestion, text: req.question }),
5817
- !skipped && answer ? /* @__PURE__ */ jsx16(Section, { label: strings.inputYourAnswer, text: answer }) : null,
5715
+ req.intro ? /* @__PURE__ */ jsx16("div", { class: `${p15}-toolui-desc`, children: req.intro }) : null,
5716
+ req.questions.map((q) => {
5717
+ const text = skipped ? "" : answers[q.key] ?? "";
5718
+ return /* @__PURE__ */ jsxs13("div", { class: `${p15}-toolui-section`, children: [
5719
+ /* @__PURE__ */ jsx16("span", { class: `${p15}-toolui-label`, children: q.question }),
5720
+ text ? /* @__PURE__ */ jsx16("p", { class: `${p15}-toolui-text`, children: text }) : null
5721
+ ] }, q.key);
5722
+ }),
5818
5723
  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
5819
5724
  ] });
5820
5725
  }
5821
- function summarizeOutput(output, strings) {
5822
- if (output == null) return "";
5823
- if (typeof output === "string") return output;
5824
- if (typeof output === "object") {
5825
- const rec = output;
5826
- if ("confirmed" in rec) return rec.confirmed ? strings.confirmYes : strings.confirmNo;
5827
- if (typeof rec.responseText === "string" && rec.responseText) return rec.responseText;
5828
- return Object.values(rec).filter((v) => typeof v === "string" || typeof v === "number").join(", ");
5726
+ function parseAnswers(reason) {
5727
+ if (!reason) return {};
5728
+ const parsed = (() => {
5729
+ try {
5730
+ return JSON.parse(reason);
5731
+ } catch {
5732
+ return void 0;
5733
+ }
5734
+ })();
5735
+ const list = parsed?.answers;
5736
+ if (!Array.isArray(list)) return {};
5737
+ const out = {};
5738
+ for (const entry of list) {
5739
+ if (!entry || typeof entry !== "object") continue;
5740
+ const { key, value } = entry;
5741
+ if (typeof key !== "string") continue;
5742
+ out[key] = Array.isArray(value) ? value.filter((v) => typeof v === "string").join(", ") : String(value ?? "");
5829
5743
  }
5830
- return String(output);
5744
+ return out;
5831
5745
  }
5832
5746
 
5833
5747
  // src/ui/tool-call.tsx
@@ -5883,6 +5797,15 @@ function MessageBubble({
5883
5797
  const reasoningVisible = useComputed5(
5884
5798
  () => showReasoning && message.partsSig.value.some((part) => part.kind === "reasoning")
5885
5799
  );
5800
+ const lastOutputIdx = useComputed5(() => {
5801
+ const list = message.partsSig.value;
5802
+ let idx = -1;
5803
+ for (let i = 0; i < list.length; i++) {
5804
+ const kind = list[i]?.kind;
5805
+ if (kind === "text" || kind === "file" || kind === "source") idx = i;
5806
+ }
5807
+ return idx;
5808
+ });
5886
5809
  const streaming = message.role === "assistant" && message.status === "streaming";
5887
5810
  const bufferedHold = responseMode === "buffered" && streaming;
5888
5811
  const working = streaming && !hasAnswerText.value;
@@ -5891,7 +5814,7 @@ function MessageBubble({
5891
5814
  const stamp = formatStamp(message.createdAt);
5892
5815
  return /* @__PURE__ */ jsx18("div", { class: `${p17}-bubble-row`, "data-role": message.role, "data-testid": tid(TID.messageBubble, message.id), children: /* @__PURE__ */ jsxs15("div", { class: `${p17}-bubble-col`, children: [
5893
5816
  /* @__PURE__ */ jsxs15("div", { class: `${p17}-bubble`, children: [
5894
- bufferedHold ? /* @__PURE__ */ jsx18(LoadingSpinner, { label: strings.loading }) : partList.map((part) => /* @__PURE__ */ jsx18(
5817
+ bufferedHold ? /* @__PURE__ */ jsx18(LoadingSpinner, { label: strings.loading }) : partList.map((part, index) => /* @__PURE__ */ jsx18(
5895
5818
  PartView,
5896
5819
  {
5897
5820
  part,
@@ -5900,7 +5823,7 @@ function MessageBubble({
5900
5823
  showReasoning,
5901
5824
  showToolCalls,
5902
5825
  showSources,
5903
- interactive,
5826
+ interactive: interactive && (part.kind !== "tool" || index > lastOutputIdx.value),
5904
5827
  superseded,
5905
5828
  tool
5906
5829
  },
@@ -5977,15 +5900,14 @@ function ToolPartView({
5977
5900
  }) {
5978
5901
  const hasApproval = useComputed5(() => part.approvalSig.value !== void 0);
5979
5902
  if (tool?.humanInLoop) {
5980
- if (isAskUserInputTool(part.toolName)) {
5903
+ if (isAskUserQuestionsTool(part.toolName)) {
5981
5904
  return /* @__PURE__ */ jsx18(
5982
- ToolAskInput,
5905
+ ToolAskQuestions,
5983
5906
  {
5984
5907
  part,
5985
5908
  strings,
5986
5909
  active: interactive,
5987
5910
  superseded,
5988
- onSubmit: tool.onResult,
5989
5911
  onDecision: tool.onDecision,
5990
5912
  onEdit: tool.onEdit
5991
5913
  }
@@ -6067,7 +5989,7 @@ function MessageList({
6067
5989
  }) {
6068
5990
  const ref = useRef5(null);
6069
5991
  const messages = useComputed6(() => messagesSig.value);
6070
- const [showJump, setShowJump] = useState7(false);
5992
+ const [showJump, setShowJump] = useState6(false);
6071
5993
  const hasHydratedRef = useRef5(false);
6072
5994
  const detachedRef = useRef5(false);
6073
5995
  const interactingRef = useRef5(false);
@@ -6354,7 +6276,7 @@ function dayLabel(createdAt, strings) {
6354
6276
  }
6355
6277
 
6356
6278
  // src/ui/conversation-list.tsx
6357
- import { useEffect as useEffect8, useState as useState8 } from "preact/hooks";
6279
+ import { useEffect as useEffect8, useState as useState7 } from "preact/hooks";
6358
6280
 
6359
6281
  // src/ui/history-groups.ts
6360
6282
  var HISTORY_BUCKETS = ["today", "yesterday", "lastWeek", "older"];
@@ -6413,8 +6335,8 @@ function ConversationList({
6413
6335
  }) {
6414
6336
  const p36 = BRAND.cssPrefix;
6415
6337
  const seed = transport.peekConversations({ visitorId });
6416
- const [state, setState] = useState8(seed ? "loaded" : "loading");
6417
- const [conversations, setChats] = useState8(seed?.conversations ?? []);
6338
+ const [state, setState] = useState7(seed ? "loaded" : "loading");
6339
+ const [conversations, setChats] = useState7(seed?.conversations ?? []);
6418
6340
  useEffect8(() => {
6419
6341
  let cancelled = false;
6420
6342
  transport.listConversations({ visitorId }).then((res) => {
@@ -7020,7 +6942,7 @@ var chatLayout = {
7020
6942
  };
7021
6943
 
7022
6944
  // src/ui/modules/help.tsx
7023
- import { useEffect as useEffect10, useMemo as useMemo2, useState as useState9 } from "preact/hooks";
6945
+ import { useEffect as useEffect10, useMemo as useMemo2, useState as useState8 } from "preact/hooks";
7024
6946
 
7025
6947
  // src/ui/back-header.tsx
7026
6948
  import { jsx as jsx25, jsxs as jsxs21 } from "preact/jsx-runtime";
@@ -7137,11 +7059,11 @@ function ArticleRow({ article, nav }) {
7137
7059
  }
7138
7060
  function HelpRoot({ transport, strings, config, nav, bus, panelProps }) {
7139
7061
  const tags = config.contentTags;
7140
- const [state, setState] = useState9("loading");
7141
- const [errorMsg, setErrorMsg] = useState9(strings.errorGeneric);
7142
- const [items, setItems] = useState9([]);
7143
- const [query, setQuery] = useState9("");
7144
- const [reloadKey, setReloadKey] = useState9(0);
7062
+ const [state, setState] = useState8("loading");
7063
+ const [errorMsg, setErrorMsg] = useState8(strings.errorGeneric);
7064
+ const [items, setItems] = useState8([]);
7065
+ const [query, setQuery] = useState8("");
7066
+ const [reloadKey, setReloadKey] = useState8(0);
7145
7067
  useEffect10(() => {
7146
7068
  let cancelled = false;
7147
7069
  setState("loading");
@@ -7195,7 +7117,7 @@ var helpLayout = {
7195
7117
  };
7196
7118
 
7197
7119
  // src/ui/modules/home.tsx
7198
- import { useEffect as useEffect11, useState as useState10 } from "preact/hooks";
7120
+ import { useEffect as useEffect11, useState as useState9 } from "preact/hooks";
7199
7121
 
7200
7122
  // src/ui/home-card.tsx
7201
7123
  import { jsx as jsx30 } from "preact/jsx-runtime";
@@ -7223,8 +7145,8 @@ function resolveGreeting(props2) {
7223
7145
  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 });
7224
7146
  function HomeRoot(props2) {
7225
7147
  const { transport, strings, config, nav, bus, panelProps } = props2;
7226
- const [recent, setRecent] = useState10(null);
7227
- const [content, setContent] = useState10([]);
7148
+ const [recent, setRecent] = useState9(null);
7149
+ const [content, setContent] = useState9([]);
7228
7150
  const tagsKey = config.contentTags?.join(",");
7229
7151
  useEffect11(() => {
7230
7152
  if (!config.showRecentConversations) return;
@@ -7314,16 +7236,16 @@ var homeLayout = {
7314
7236
  };
7315
7237
 
7316
7238
  // src/ui/modules/news.tsx
7317
- import { useEffect as useEffect12, useState as useState11 } from "preact/hooks";
7239
+ import { useEffect as useEffect12, useState as useState10 } from "preact/hooks";
7318
7240
  import { jsx as jsx32, jsxs as jsxs27 } from "preact/jsx-runtime";
7319
7241
  var p29 = BRAND.cssPrefix;
7320
7242
  var log14 = logger.scope("news");
7321
7243
  function NewsRoot({ transport, strings, config, nav, bus, panelProps }) {
7322
7244
  const tags = config.contentTags;
7323
- const [state, setState] = useState11("loading");
7324
- const [errorMsg, setErrorMsg] = useState11(strings.errorGeneric);
7325
- const [items, setItems] = useState11([]);
7326
- const [reloadKey, setReloadKey] = useState11(0);
7245
+ const [state, setState] = useState10("loading");
7246
+ const [errorMsg, setErrorMsg] = useState10(strings.errorGeneric);
7247
+ const [items, setItems] = useState10([]);
7248
+ const [reloadKey, setReloadKey] = useState10(0);
7327
7249
  useEffect12(() => {
7328
7250
  let cancelled = false;
7329
7251
  setState("loading");
@@ -7446,15 +7368,15 @@ function IframeView({ url, title, strings, onBack, actions }) {
7446
7368
  }
7447
7369
 
7448
7370
  // src/ui/content-view.tsx
7449
- import { useCallback as useCallback3, useEffect as useEffect13, useState as useState12 } from "preact/hooks";
7371
+ import { useCallback as useCallback3, useEffect as useEffect13, useState as useState11 } from "preact/hooks";
7450
7372
  import { jsx as jsx35, jsxs as jsxs30 } from "preact/jsx-runtime";
7451
7373
  var p32 = BRAND.cssPrefix;
7452
7374
  var log15 = logger.scope("content");
7453
7375
  var READ_DWELL_MS = 5e3;
7454
7376
  function ContentView({ id, title, transport, strings, bus, onBack, actions }) {
7455
- const [item, setItem] = useState12(null);
7456
- const [failed, setFailed] = useState12(false);
7457
- const [reloadKey, setReloadKey] = useState12(0);
7377
+ const [item, setItem] = useState11(null);
7378
+ const [failed, setFailed] = useState11(false);
7379
+ const [reloadKey, setReloadKey] = useState11(0);
7458
7380
  const retry = useCallback3(() => {
7459
7381
  setFailed(false);
7460
7382
  setItem(null);
@@ -7698,11 +7620,11 @@ function ModulesEmpty({ strings, onClose }) {
7698
7620
  }
7699
7621
 
7700
7622
  // src/ui/use-launcher-callout.ts
7701
- import { useCallback as useCallback5, useEffect as useEffect15, useState as useState13 } from "preact/hooks";
7623
+ import { useCallback as useCallback5, useEffect as useEffect15, useState as useState12 } from "preact/hooks";
7702
7624
  function useLauncherCallout({ callout, persistence }) {
7703
7625
  const textKey = callout?.text ?? "";
7704
7626
  const persistent = callout?.persistent ?? true;
7705
- const [dismissed, setDismissed] = useState13(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
7627
+ const [dismissed, setDismissed] = useState12(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
7706
7628
  useEffect15(() => {
7707
7629
  setDismissed(persistent ? false : persistence.loadCalloutDismissed(textKey));
7708
7630
  }, [textKey, persistent, persistence]);
@@ -7731,21 +7653,21 @@ function isAbortError(error) {
7731
7653
  return error instanceof DOMException ? error.name === "AbortError" : error?.name === "AbortError";
7732
7654
  }
7733
7655
  function App({ options, hostElement, bus }) {
7734
- const [persistence] = useState14(
7656
+ const [persistence] = useState13(
7735
7657
  () => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
7736
7658
  );
7737
- const [visitorId, setVisitorId] = useState14(() => persistence.getVisitorId());
7659
+ const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
7738
7660
  const initialSettings = persistence.loadUserPrefs();
7739
- const [activeLocale, setActiveLocale] = useState14(() => initialSettings.locale ?? options.locale);
7740
- const [activeThemeMode, setActiveThemeMode] = useState14(
7661
+ const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
7662
+ const [activeThemeMode, setActiveThemeMode] = useState13(
7741
7663
  () => initialSettings.themeMode ?? options.themeMode
7742
7664
  );
7743
- const [activeTextSize, setActiveTextSize] = useState14(() => initialSettings.textSize ?? options.textSize);
7665
+ const [activeTextSize, setActiveTextSize] = useState13(() => initialSettings.textSize ?? options.textSize);
7744
7666
  const conversationIdSig = useSignal(persistence.loadConversationId());
7745
7667
  const messagesSig = useSignal([]);
7746
7668
  const unreadCountSig = useSignal(0);
7747
- const [loadingMessages, setLoadingMessages] = useState14(false);
7748
- const [formMarkers, setFormMarkers] = useState14([]);
7669
+ const [loadingMessages, setLoadingMessages] = useState13(false);
7670
+ const [formMarkers, setFormMarkers] = useState13([]);
7749
7671
  function landingTab() {
7750
7672
  const list = options.modules.list;
7751
7673
  const ids = new Set(list.map((m) => m.id));
@@ -7764,15 +7686,15 @@ function App({ options, hostElement, bus }) {
7764
7686
  const homeNav = homeNavRef.current;
7765
7687
  const chatTabIdRef = useRef9(void 0);
7766
7688
  chatTabIdRef.current = chatTabId();
7767
- const [conversationReady, setConversationReady] = useState14(false);
7768
- const [remoteForms, setRemoteForms] = useState14(null);
7769
- const [formsReady, setFormsReady] = useState14(false);
7689
+ const [conversationReady, setConversationReady] = useState13(false);
7690
+ const [remoteForms, setRemoteForms] = useState13(null);
7691
+ const [formsReady, setFormsReady] = useState13(false);
7770
7692
  const isInlineLike = options.mode === "standalone" || options.mode === "inline";
7771
7693
  const initialPanelRef = useRef9(
7772
7694
  resolveInitialPanelState(options, currentViewportWidth(), persistence.loadPanelOpen(), persistence.loadPanelSize())
7773
7695
  );
7774
- const [isOpen, setIsOpen] = useState14(initialPanelRef.current.panelOpen);
7775
- const [activated, setActivated] = useState14(initialPanelRef.current.panelOpen);
7696
+ const [isOpen, setIsOpen] = useState13(initialPanelRef.current.panelOpen);
7697
+ const [activated, setActivated] = useState13(initialPanelRef.current.panelOpen);
7776
7698
  const activatedRef = useRef9(activated);
7777
7699
  activatedRef.current = activated;
7778
7700
  const pendingThreadRef = useRef9(false);
@@ -7781,7 +7703,7 @@ function App({ options, hostElement, bus }) {
7781
7703
  if (isOpen) setActivated(true);
7782
7704
  }, [isOpen]);
7783
7705
  const initialPanelApplied = useRef9(false);
7784
- const [launcherLeaving, setLauncherLeaving] = useState14(false);
7706
+ const [launcherLeaving, setLauncherLeaving] = useState13(false);
7785
7707
  const { dismissed: calloutDismissed, dismissCallout: dismissCalloutRaw } = useLauncherCallout({
7786
7708
  callout: options.launcher.callout,
7787
7709
  persistence
@@ -7792,21 +7714,21 @@ function App({ options, hostElement, bus }) {
7792
7714
  bus.emit("calloutDismiss", void 0);
7793
7715
  dismissCalloutRaw();
7794
7716
  }, [bus, dismissCalloutRaw]);
7795
- const [panelSize, setPanelSize] = useState14(initialPanelRef.current.panelSize);
7717
+ const [panelSize, setPanelSize] = useState13(initialPanelRef.current.panelSize);
7796
7718
  const initialSizeApplied = useRef9(false);
7797
- const [view, setView] = useState14("chat");
7798
- const [canSend, setCanSend] = useState14(true);
7799
- const [streaming, setStreaming] = useState14(false);
7800
- const [agent, setAgent] = useState14(null);
7801
- const [suggestions, setSuggestions] = useState14([]);
7802
- const [activeCancel, setActiveCancel] = useState14(null);
7803
- const [activeDetach, setActiveDetach] = useState14(null);
7719
+ const [view, setView] = useState13("chat");
7720
+ const [canSend, setCanSend] = useState13(true);
7721
+ const [streaming, setStreaming] = useState13(false);
7722
+ const [agent, setAgent] = useState13(null);
7723
+ const [suggestions, setSuggestions] = useState13([]);
7724
+ const [activeCancel, setActiveCancel] = useState13(null);
7725
+ const [activeDetach, setActiveDetach] = useState13(null);
7804
7726
  const stringsRef = useRef9(options.strings);
7805
- const [parsedSite, setParsedSite] = useState14(void 0);
7806
- const [parsedBlocks, setParsedBlocks] = useState14(void 0);
7807
- const [sidebarCollapsed, setSidebarCollapsed] = useState14(() => persistence.loadSidebarCollapsed() ?? false);
7808
- const [formContext, setFormContext] = useState14({});
7809
- const [transport] = useState14(
7727
+ const [parsedSite, setParsedSite] = useState13(void 0);
7728
+ const [parsedBlocks, setParsedBlocks] = useState13(void 0);
7729
+ const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
7730
+ const [formContext, setFormContext] = useState13({});
7731
+ const [transport] = useState13(
7810
7732
  () => new AgentTransport({
7811
7733
  agentApiBaseUrl: options.agentApiBaseUrl,
7812
7734
  dataApiBaseUrl: options.dataApiBaseUrl,
@@ -7818,8 +7740,8 @@ function App({ options, hostElement, bus }) {
7818
7740
  endpoints: options.endpoints
7819
7741
  })
7820
7742
  );
7821
- const [reducer] = useState14(() => new StreamReducer(messagesSig));
7822
- const [feedback] = useState14(() => new FeedbackBus(options.sound, options.haptics));
7743
+ const [reducer] = useState13(() => new StreamReducer(messagesSig));
7744
+ const [feedback] = useState13(() => new FeedbackBus(options.sound, options.haptics));
7823
7745
  const patchAndSync = useCallback6(
7824
7746
  (patch) => {
7825
7747
  persistence.patchUserPrefs(patch);