@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/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.1" : "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
@@ -5924,6 +5838,15 @@ function MessageBubble({
5924
5838
  const reasoningVisible = useComputed5(
5925
5839
  () => showReasoning && message.partsSig.value.some((part) => part.kind === "reasoning")
5926
5840
  );
5841
+ const lastOutputIdx = useComputed5(() => {
5842
+ const list = message.partsSig.value;
5843
+ let idx = -1;
5844
+ for (let i = 0; i < list.length; i++) {
5845
+ const kind = list[i]?.kind;
5846
+ if (kind === "text" || kind === "file" || kind === "source") idx = i;
5847
+ }
5848
+ return idx;
5849
+ });
5927
5850
  const streaming = message.role === "assistant" && message.status === "streaming";
5928
5851
  const bufferedHold = responseMode === "buffered" && streaming;
5929
5852
  const working = streaming && !hasAnswerText.value;
@@ -5932,7 +5855,7 @@ function MessageBubble({
5932
5855
  const stamp = formatStamp(message.createdAt);
5933
5856
  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: [
5934
5857
  /* @__PURE__ */ jsxs15("div", { class: `${p17}-bubble`, children: [
5935
- bufferedHold ? /* @__PURE__ */ jsx18(LoadingSpinner, { label: strings.loading }) : partList.map((part) => /* @__PURE__ */ jsx18(
5858
+ bufferedHold ? /* @__PURE__ */ jsx18(LoadingSpinner, { label: strings.loading }) : partList.map((part, index) => /* @__PURE__ */ jsx18(
5936
5859
  PartView,
5937
5860
  {
5938
5861
  part,
@@ -5941,7 +5864,7 @@ function MessageBubble({
5941
5864
  showReasoning,
5942
5865
  showToolCalls,
5943
5866
  showSources,
5944
- interactive,
5867
+ interactive: interactive && (part.kind !== "tool" || index > lastOutputIdx.value),
5945
5868
  superseded,
5946
5869
  tool
5947
5870
  },
@@ -6018,15 +5941,14 @@ function ToolPartView({
6018
5941
  }) {
6019
5942
  const hasApproval = useComputed5(() => part.approvalSig.value !== void 0);
6020
5943
  if (tool?.humanInLoop) {
6021
- if (isAskUserInputTool(part.toolName)) {
5944
+ if (isAskUserQuestionsTool(part.toolName)) {
6022
5945
  return /* @__PURE__ */ jsx18(
6023
- ToolAskInput,
5946
+ ToolAskQuestions,
6024
5947
  {
6025
5948
  part,
6026
5949
  strings,
6027
5950
  active: interactive,
6028
5951
  superseded,
6029
- onSubmit: tool.onResult,
6030
5952
  onDecision: tool.onDecision,
6031
5953
  onEdit: tool.onEdit
6032
5954
  }
@@ -6108,7 +6030,7 @@ function MessageList({
6108
6030
  }) {
6109
6031
  const ref = useRef5(null);
6110
6032
  const messages = useComputed6(() => messagesSig.value);
6111
- const [showJump, setShowJump] = useState7(false);
6033
+ const [showJump, setShowJump] = useState6(false);
6112
6034
  const hasHydratedRef = useRef5(false);
6113
6035
  const detachedRef = useRef5(false);
6114
6036
  const interactingRef = useRef5(false);
@@ -6395,7 +6317,7 @@ function dayLabel(createdAt, strings) {
6395
6317
  }
6396
6318
 
6397
6319
  // src/ui/conversation-list.tsx
6398
- import { useEffect as useEffect8, useState as useState8 } from "preact/hooks";
6320
+ import { useEffect as useEffect8, useState as useState7 } from "preact/hooks";
6399
6321
 
6400
6322
  // src/ui/history-groups.ts
6401
6323
  var HISTORY_BUCKETS = ["today", "yesterday", "lastWeek", "older"];
@@ -6454,8 +6376,8 @@ function ConversationList({
6454
6376
  }) {
6455
6377
  const p36 = BRAND.cssPrefix;
6456
6378
  const seed = transport.peekConversations({ visitorId });
6457
- const [state, setState] = useState8(seed ? "loaded" : "loading");
6458
- const [conversations, setChats] = useState8(seed?.conversations ?? []);
6379
+ const [state, setState] = useState7(seed ? "loaded" : "loading");
6380
+ const [conversations, setChats] = useState7(seed?.conversations ?? []);
6459
6381
  useEffect8(() => {
6460
6382
  let cancelled = false;
6461
6383
  transport.listConversations({ visitorId }).then((res) => {
@@ -7061,7 +6983,7 @@ var chatLayout = {
7061
6983
  };
7062
6984
 
7063
6985
  // src/ui/modules/help.tsx
7064
- import { useEffect as useEffect10, useMemo as useMemo2, useState as useState9 } from "preact/hooks";
6986
+ import { useEffect as useEffect10, useMemo as useMemo2, useState as useState8 } from "preact/hooks";
7065
6987
 
7066
6988
  // src/ui/back-header.tsx
7067
6989
  import { jsx as jsx25, jsxs as jsxs21 } from "preact/jsx-runtime";
@@ -7178,11 +7100,11 @@ function ArticleRow({ article, nav }) {
7178
7100
  }
7179
7101
  function HelpRoot({ transport, strings, config, nav, bus, panelProps }) {
7180
7102
  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);
7103
+ const [state, setState] = useState8("loading");
7104
+ const [errorMsg, setErrorMsg] = useState8(strings.errorGeneric);
7105
+ const [items, setItems] = useState8([]);
7106
+ const [query, setQuery] = useState8("");
7107
+ const [reloadKey, setReloadKey] = useState8(0);
7186
7108
  useEffect10(() => {
7187
7109
  let cancelled = false;
7188
7110
  setState("loading");
@@ -7236,7 +7158,7 @@ var helpLayout = {
7236
7158
  };
7237
7159
 
7238
7160
  // src/ui/modules/home.tsx
7239
- import { useEffect as useEffect11, useState as useState10 } from "preact/hooks";
7161
+ import { useEffect as useEffect11, useState as useState9 } from "preact/hooks";
7240
7162
 
7241
7163
  // src/ui/home-card.tsx
7242
7164
  import { jsx as jsx30 } from "preact/jsx-runtime";
@@ -7264,8 +7186,8 @@ function resolveGreeting(props2) {
7264
7186
  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
7187
  function HomeRoot(props2) {
7266
7188
  const { transport, strings, config, nav, bus, panelProps } = props2;
7267
- const [recent, setRecent] = useState10(null);
7268
- const [content, setContent] = useState10([]);
7189
+ const [recent, setRecent] = useState9(null);
7190
+ const [content, setContent] = useState9([]);
7269
7191
  const tagsKey = config.contentTags?.join(",");
7270
7192
  useEffect11(() => {
7271
7193
  if (!config.showRecentConversations) return;
@@ -7355,16 +7277,16 @@ var homeLayout = {
7355
7277
  };
7356
7278
 
7357
7279
  // src/ui/modules/news.tsx
7358
- import { useEffect as useEffect12, useState as useState11 } from "preact/hooks";
7280
+ import { useEffect as useEffect12, useState as useState10 } from "preact/hooks";
7359
7281
  import { jsx as jsx32, jsxs as jsxs27 } from "preact/jsx-runtime";
7360
7282
  var p29 = BRAND.cssPrefix;
7361
7283
  var log15 = logger.scope("news");
7362
7284
  function NewsRoot({ transport, strings, config, nav, bus, panelProps }) {
7363
7285
  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);
7286
+ const [state, setState] = useState10("loading");
7287
+ const [errorMsg, setErrorMsg] = useState10(strings.errorGeneric);
7288
+ const [items, setItems] = useState10([]);
7289
+ const [reloadKey, setReloadKey] = useState10(0);
7368
7290
  useEffect12(() => {
7369
7291
  let cancelled = false;
7370
7292
  setState("loading");
@@ -7487,15 +7409,15 @@ function IframeView({ url, title, strings, onBack, actions }) {
7487
7409
  }
7488
7410
 
7489
7411
  // src/ui/content-view.tsx
7490
- import { useCallback as useCallback3, useEffect as useEffect13, useState as useState12 } from "preact/hooks";
7412
+ import { useCallback as useCallback3, useEffect as useEffect13, useState as useState11 } from "preact/hooks";
7491
7413
  import { jsx as jsx35, jsxs as jsxs30 } from "preact/jsx-runtime";
7492
7414
  var p32 = BRAND.cssPrefix;
7493
7415
  var log16 = logger.scope("content");
7494
7416
  var READ_DWELL_MS = 5e3;
7495
7417
  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);
7418
+ const [item, setItem] = useState11(null);
7419
+ const [failed, setFailed] = useState11(false);
7420
+ const [reloadKey, setReloadKey] = useState11(0);
7499
7421
  const retry = useCallback3(() => {
7500
7422
  setFailed(false);
7501
7423
  setItem(null);
@@ -7739,11 +7661,11 @@ function ModulesEmpty({ strings, onClose }) {
7739
7661
  }
7740
7662
 
7741
7663
  // src/ui/use-launcher-callout.ts
7742
- import { useCallback as useCallback5, useEffect as useEffect15, useState as useState13 } from "preact/hooks";
7664
+ import { useCallback as useCallback5, useEffect as useEffect15, useState as useState12 } from "preact/hooks";
7743
7665
  function useLauncherCallout({ callout, persistence }) {
7744
7666
  const textKey = callout?.text ?? "";
7745
7667
  const persistent = callout?.persistent ?? true;
7746
- const [dismissed, setDismissed] = useState13(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
7668
+ const [dismissed, setDismissed] = useState12(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
7747
7669
  useEffect15(() => {
7748
7670
  setDismissed(persistent ? false : persistence.loadCalloutDismissed(textKey));
7749
7671
  }, [textKey, persistent, persistence]);
@@ -7772,21 +7694,21 @@ function isAbortError(error) {
7772
7694
  return error instanceof DOMException ? error.name === "AbortError" : error?.name === "AbortError";
7773
7695
  }
7774
7696
  function App({ options, hostElement, bus }) {
7775
- const [persistence] = useState14(
7697
+ const [persistence] = useState13(
7776
7698
  () => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
7777
7699
  );
7778
- const [visitorId, setVisitorId] = useState14(() => persistence.getVisitorId());
7700
+ const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
7779
7701
  const initialSettings = persistence.loadUserPrefs();
7780
- const [activeLocale, setActiveLocale] = useState14(() => initialSettings.locale ?? options.locale);
7781
- const [activeThemeMode, setActiveThemeMode] = useState14(
7702
+ const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
7703
+ const [activeThemeMode, setActiveThemeMode] = useState13(
7782
7704
  () => initialSettings.themeMode ?? options.themeMode
7783
7705
  );
7784
- const [activeTextSize, setActiveTextSize] = useState14(() => initialSettings.textSize ?? options.textSize);
7706
+ const [activeTextSize, setActiveTextSize] = useState13(() => initialSettings.textSize ?? options.textSize);
7785
7707
  const conversationIdSig = useSignal(persistence.loadConversationId());
7786
7708
  const messagesSig = useSignal([]);
7787
7709
  const unreadCountSig = useSignal(0);
7788
- const [loadingMessages, setLoadingMessages] = useState14(false);
7789
- const [formMarkers, setFormMarkers] = useState14([]);
7710
+ const [loadingMessages, setLoadingMessages] = useState13(false);
7711
+ const [formMarkers, setFormMarkers] = useState13([]);
7790
7712
  function landingTab() {
7791
7713
  const list = options.modules.list;
7792
7714
  const ids = new Set(list.map((m) => m.id));
@@ -7805,15 +7727,15 @@ function App({ options, hostElement, bus }) {
7805
7727
  const homeNav = homeNavRef.current;
7806
7728
  const chatTabIdRef = useRef9(void 0);
7807
7729
  chatTabIdRef.current = chatTabId();
7808
- const [conversationReady, setConversationReady] = useState14(false);
7809
- const [remoteForms, setRemoteForms] = useState14(null);
7810
- const [formsReady, setFormsReady] = useState14(false);
7730
+ const [conversationReady, setConversationReady] = useState13(false);
7731
+ const [remoteForms, setRemoteForms] = useState13(null);
7732
+ const [formsReady, setFormsReady] = useState13(false);
7811
7733
  const isInlineLike = options.mode === "standalone" || options.mode === "inline";
7812
7734
  const initialPanelRef = useRef9(
7813
7735
  resolveInitialPanelState(options, currentViewportWidth(), persistence.loadPanelOpen(), persistence.loadPanelSize())
7814
7736
  );
7815
- const [isOpen, setIsOpen] = useState14(initialPanelRef.current.panelOpen);
7816
- const [activated, setActivated] = useState14(initialPanelRef.current.panelOpen);
7737
+ const [isOpen, setIsOpen] = useState13(initialPanelRef.current.panelOpen);
7738
+ const [activated, setActivated] = useState13(initialPanelRef.current.panelOpen);
7817
7739
  const activatedRef = useRef9(activated);
7818
7740
  activatedRef.current = activated;
7819
7741
  const pendingThreadRef = useRef9(false);
@@ -7822,7 +7744,7 @@ function App({ options, hostElement, bus }) {
7822
7744
  if (isOpen) setActivated(true);
7823
7745
  }, [isOpen]);
7824
7746
  const initialPanelApplied = useRef9(false);
7825
- const [launcherLeaving, setLauncherLeaving] = useState14(false);
7747
+ const [launcherLeaving, setLauncherLeaving] = useState13(false);
7826
7748
  const { dismissed: calloutDismissed, dismissCallout: dismissCalloutRaw } = useLauncherCallout({
7827
7749
  callout: options.launcher.callout,
7828
7750
  persistence
@@ -7833,21 +7755,21 @@ function App({ options, hostElement, bus }) {
7833
7755
  bus.emit("calloutDismiss", void 0);
7834
7756
  dismissCalloutRaw();
7835
7757
  }, [bus, dismissCalloutRaw]);
7836
- const [panelSize, setPanelSize] = useState14(initialPanelRef.current.panelSize);
7758
+ const [panelSize, setPanelSize] = useState13(initialPanelRef.current.panelSize);
7837
7759
  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);
7760
+ const [view, setView] = useState13("chat");
7761
+ const [canSend, setCanSend] = useState13(true);
7762
+ const [streaming, setStreaming] = useState13(false);
7763
+ const [agent, setAgent] = useState13(null);
7764
+ const [suggestions, setSuggestions] = useState13([]);
7765
+ const [activeCancel, setActiveCancel] = useState13(null);
7766
+ const [activeDetach, setActiveDetach] = useState13(null);
7845
7767
  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(
7768
+ const [parsedSite, setParsedSite] = useState13(void 0);
7769
+ const [parsedBlocks, setParsedBlocks] = useState13(void 0);
7770
+ const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
7771
+ const [formContext, setFormContext] = useState13({});
7772
+ const [transport] = useState13(
7851
7773
  () => new AgentTransport({
7852
7774
  agentApiBaseUrl: options.agentApiBaseUrl,
7853
7775
  dataApiBaseUrl: options.dataApiBaseUrl,
@@ -7859,8 +7781,8 @@ function App({ options, hostElement, bus }) {
7859
7781
  endpoints: options.endpoints
7860
7782
  })
7861
7783
  );
7862
- const [reducer] = useState14(() => new StreamReducer(messagesSig));
7863
- const [feedback] = useState14(() => new FeedbackBus(options.sound, options.haptics));
7784
+ const [reducer] = useState13(() => new StreamReducer(messagesSig));
7785
+ const [feedback] = useState13(() => new FeedbackBus(options.sound, options.haptics));
7864
7786
  const patchAndSync = useCallback6(
7865
7787
  (patch) => {
7866
7788
  persistence.patchUserPrefs(patch);