@helpai/elements 0.12.3 → 0.13.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/configurator.mjs +171 -87
- package/elements-web-component.esm.js +27 -27
- package/elements-web-component.esm.js.map +4 -4
- package/elements.cjs.js +27 -27
- package/elements.cjs.js.map +4 -4
- package/elements.esm.js +27 -27
- package/elements.esm.js.map +4 -4
- package/elements.js +28 -28
- package/elements.js.map +4 -4
- package/index.d.ts +143 -2
- package/index.mjs +1469 -502
- package/package.json +1 -1
- package/schema.d.ts +155 -30
- package/schema.json +476 -3
- package/schema.mjs +178 -89
- package/style.css +1 -1
- package/web-component.mjs +1486 -523
package/index.mjs
CHANGED
|
@@ -6,8 +6,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
6
6
|
import { h, render } from "preact";
|
|
7
7
|
|
|
8
8
|
// src/ui/app.tsx
|
|
9
|
-
import { useCallback as useCallback6, useEffect as useEffect17, useMemo as useMemo3, useRef as useRef8, useState as
|
|
10
|
-
import { useSignal } from "@preact/signals";
|
|
9
|
+
import { useCallback as useCallback6, useEffect as useEffect17, useMemo as useMemo3, useRef as useRef8, useState as useState13 } from "preact/hooks";
|
|
10
|
+
import { useSignal as useSignal2 } from "@preact/signals";
|
|
11
11
|
|
|
12
12
|
// src/core/brand.ts
|
|
13
13
|
var BRAND = {
|
|
@@ -105,15 +105,154 @@ var STRINGS_EN = {
|
|
|
105
105
|
newsEmpty: "No news yet",
|
|
106
106
|
newsLoading: "Loading news\u2026",
|
|
107
107
|
newsBack: "Back to news",
|
|
108
|
-
newsPublishedAt: "Published {date}"
|
|
108
|
+
newsPublishedAt: "Published {date}",
|
|
109
|
+
// ── Forms + human-in-the-loop (intake / ask-input / approval) ───
|
|
110
|
+
intakeSubmit: "Start chat",
|
|
111
|
+
intakeSkip: "Skip for now",
|
|
112
|
+
formRequired: "This field is required",
|
|
113
|
+
formInvalidEmail: "Enter a valid email address",
|
|
114
|
+
formInvalidTel: "Enter a valid phone number",
|
|
115
|
+
formInvalidUrl: "Enter a valid URL",
|
|
116
|
+
formInvalidNumber: "Enter a valid number",
|
|
117
|
+
formTooShort: "Too short (min {min} characters)",
|
|
118
|
+
formTooLong: "Too long (max {max} characters)",
|
|
119
|
+
formNumberTooSmall: "Must be at least {min}",
|
|
120
|
+
formNumberTooLarge: "Must be at most {max}",
|
|
121
|
+
formPatternMismatch: "Please match the requested format",
|
|
122
|
+
formChooseAtLeast: "Choose at least {min}",
|
|
123
|
+
formChooseAtMost: "Choose at most {max}",
|
|
124
|
+
formOther: "Other",
|
|
125
|
+
formOtherPlaceholder: "Type your answer\u2026",
|
|
126
|
+
inputRequired: "Input required",
|
|
127
|
+
inputSubmit: "Submit",
|
|
128
|
+
inputSkip: "Skip",
|
|
129
|
+
inputSubmitted: "Answer submitted",
|
|
130
|
+
approvalRequired: "Approval required",
|
|
131
|
+
approve: "Approve",
|
|
132
|
+
reject: "Reject",
|
|
133
|
+
approved: "Approved",
|
|
134
|
+
rejected: "Rejected",
|
|
135
|
+
approvalReason: "Add a reason (optional)",
|
|
136
|
+
stepNoLongerActive: "This request is no longer active."
|
|
137
|
+
};
|
|
138
|
+
var STRINGS_FR = {
|
|
139
|
+
attach: "Joindre des fichiers",
|
|
140
|
+
attachmentMimeRejected: "Type de fichier non pris en charge",
|
|
141
|
+
attachmentTooLarge: "Le fichier est trop volumineux",
|
|
142
|
+
attachmentTooMany: "Limite de pi\xE8ces jointes atteinte",
|
|
143
|
+
chatClosed: "Cette conversation est ferm\xE9e",
|
|
144
|
+
close: "Fermer",
|
|
145
|
+
collapse: "R\xE9duire",
|
|
146
|
+
collapseSidebar: "R\xE9duire la barre lat\xE9rale",
|
|
147
|
+
composerPlaceholder: "\xC9crivez un message\u2026",
|
|
148
|
+
dateLastWeek: "7 derniers jours",
|
|
149
|
+
dateOlder: "Plus ancien",
|
|
150
|
+
dateToday: "Aujourd'hui",
|
|
151
|
+
dateYesterday: "Hier",
|
|
152
|
+
dropZone: "D\xE9posez les fichiers \xE0 joindre",
|
|
153
|
+
errorGeneric: "Une erreur s'est produite",
|
|
154
|
+
errorRateLimited: "Trop de requ\xEAtes \u2014 veuillez r\xE9essayer dans un instant.",
|
|
155
|
+
errorRetry: "R\xE9essayer",
|
|
156
|
+
expand: "Agrandir",
|
|
157
|
+
expandSidebar: "D\xE9velopper la barre lat\xE9rale",
|
|
158
|
+
exitFullscreen: "Quitter le plein \xE9cran",
|
|
159
|
+
fullscreen: "Plein \xE9cran",
|
|
160
|
+
history: "Historique",
|
|
161
|
+
historyBack: "Retour au chat",
|
|
162
|
+
historyEmpty: "Aucune conversation pour le moment",
|
|
163
|
+
historyLoading: "Chargement de vos conversations\u2026",
|
|
164
|
+
historyNewChat: "Nouvelle conversation",
|
|
165
|
+
historyTitle: "Historique des conversations",
|
|
166
|
+
language: "Langue",
|
|
167
|
+
launcherOpen: "Ouvrir le chat",
|
|
168
|
+
messagesLoading: "Chargement de la conversation\u2026",
|
|
169
|
+
micStart: "D\xE9marrer la saisie vocale",
|
|
170
|
+
micStop: "Arr\xEAter la saisie vocale",
|
|
171
|
+
micUnsupported: "La saisie vocale n'est pas prise en charge par ce navigateur",
|
|
172
|
+
moreActions: "Plus d'actions",
|
|
173
|
+
newConversation: "Nouvelle conversation",
|
|
174
|
+
panelTitle: "Chat",
|
|
175
|
+
popOut: "Ouvrir dans un nouvel onglet",
|
|
176
|
+
resizeHandle: "Glisser pour redimensionner",
|
|
177
|
+
scrollToBottom: "Aller au plus r\xE9cent",
|
|
178
|
+
send: "Envoyer",
|
|
179
|
+
soundOff: "Son d\xE9sactiv\xE9",
|
|
180
|
+
soundOn: "Son activ\xE9",
|
|
181
|
+
startNewConversation: "D\xE9marrer une nouvelle conversation",
|
|
182
|
+
stop: "Arr\xEAter",
|
|
183
|
+
theme: "Th\xE8me",
|
|
184
|
+
themeAuto: "Auto (syst\xE8me)",
|
|
185
|
+
themeDark: "Sombre",
|
|
186
|
+
themeLight: "Clair",
|
|
187
|
+
loading: "Chargement\u2026",
|
|
188
|
+
thinking: "R\xE9flexion\u2026",
|
|
189
|
+
thoughts: "R\xE9flexions",
|
|
190
|
+
usedTool: "Outil utilis\xE9",
|
|
191
|
+
// ── Messenger modules ──────────────────────────────────────────
|
|
192
|
+
tabHome: "Accueil",
|
|
193
|
+
tabMessages: "Messages",
|
|
194
|
+
tabHelp: "Aide",
|
|
195
|
+
tabNews: "Actualit\xE9s",
|
|
196
|
+
modulesEmpty: "Rien pour le moment",
|
|
197
|
+
moduleBack: "Retour",
|
|
198
|
+
contentLoading: "Chargement\u2026",
|
|
199
|
+
homeGreeting: "Comment pouvons-nous vous aider ?",
|
|
200
|
+
homeGreetingNamed: "Bonjour {name} \u{1F44B}",
|
|
201
|
+
homeGreetingLead: "Comment pouvons-nous vous aider ?",
|
|
202
|
+
homeSearchPlaceholder: "Rechercher de l'aide",
|
|
203
|
+
homeContentTitle: "Articles populaires",
|
|
204
|
+
helpTitle: "Aide",
|
|
205
|
+
helpSearchPlaceholder: "Rechercher de l'aide",
|
|
206
|
+
helpEmpty: "Aucun article d'aide pour le moment",
|
|
207
|
+
helpLoading: "Chargement de l'aide\u2026",
|
|
208
|
+
helpSearchEmpty: "Aucun r\xE9sultat trouv\xE9",
|
|
209
|
+
newsTitle: "Actualit\xE9s",
|
|
210
|
+
newsEmpty: "Aucune actualit\xE9 pour le moment",
|
|
211
|
+
newsLoading: "Chargement des actualit\xE9s\u2026",
|
|
212
|
+
newsBack: "Retour aux actualit\xE9s",
|
|
213
|
+
newsPublishedAt: "Publi\xE9 le {date}",
|
|
214
|
+
// ── Forms + human-in-the-loop (intake / ask-input / approval) ───
|
|
215
|
+
intakeSubmit: "D\xE9marrer le chat",
|
|
216
|
+
intakeSkip: "Ignorer pour l'instant",
|
|
217
|
+
formRequired: "Ce champ est obligatoire",
|
|
218
|
+
formInvalidEmail: "Saisissez une adresse e-mail valide",
|
|
219
|
+
formInvalidTel: "Saisissez un num\xE9ro de t\xE9l\xE9phone valide",
|
|
220
|
+
formInvalidUrl: "Saisissez une URL valide",
|
|
221
|
+
formInvalidNumber: "Saisissez un nombre valide",
|
|
222
|
+
formTooShort: "Trop court (min. {min} caract\xE8res)",
|
|
223
|
+
formTooLong: "Trop long (max. {max} caract\xE8res)",
|
|
224
|
+
formNumberTooSmall: "Doit \xEAtre au moins {min}",
|
|
225
|
+
formNumberTooLarge: "Doit \xEAtre au plus {max}",
|
|
226
|
+
formPatternMismatch: "Veuillez respecter le format demand\xE9",
|
|
227
|
+
formChooseAtLeast: "Choisissez au moins {min}",
|
|
228
|
+
formChooseAtMost: "Choisissez au plus {max}",
|
|
229
|
+
formOther: "Autre",
|
|
230
|
+
formOtherPlaceholder: "Saisissez votre r\xE9ponse\u2026",
|
|
231
|
+
inputRequired: "Saisie requise",
|
|
232
|
+
inputSubmit: "Envoyer",
|
|
233
|
+
inputSkip: "Ignorer",
|
|
234
|
+
inputSubmitted: "R\xE9ponse envoy\xE9e",
|
|
235
|
+
approvalRequired: "Approbation requise",
|
|
236
|
+
approve: "Approuver",
|
|
237
|
+
reject: "Refuser",
|
|
238
|
+
approved: "Approuv\xE9",
|
|
239
|
+
rejected: "Refus\xE9",
|
|
240
|
+
approvalReason: "Ajouter une raison (facultatif)",
|
|
241
|
+
stepNoLongerActive: "Cette demande n'est plus active."
|
|
242
|
+
};
|
|
243
|
+
var BUILTIN_STRINGS = {
|
|
244
|
+
en: STRINGS_EN,
|
|
245
|
+
fr: STRINGS_FR
|
|
109
246
|
};
|
|
110
247
|
function resolveStrings(locale, override) {
|
|
111
248
|
const tag = primaryTag(locale);
|
|
112
249
|
const isNested = isNestedShape(override);
|
|
250
|
+
const builtinLocale = tag === "en" ? {} : BUILTIN_STRINGS[tag] ?? {};
|
|
113
251
|
const localeOverride = isNested ? override[tag] ?? {} : override ?? {};
|
|
114
252
|
const enOverride = isNested ? override.en ?? {} : {};
|
|
115
253
|
return {
|
|
116
254
|
...STRINGS_EN,
|
|
255
|
+
...builtinLocale,
|
|
117
256
|
...enOverride,
|
|
118
257
|
...localeOverride
|
|
119
258
|
};
|
|
@@ -308,11 +447,14 @@ var DEFAULT_ATTACHMENTS = {
|
|
|
308
447
|
var DEFAULT_WELCOME = { animation: "typewriter", speed: 60 };
|
|
309
448
|
var DEFAULT_FEATURES = {
|
|
310
449
|
files: true,
|
|
311
|
-
voice: "local"
|
|
450
|
+
voice: "local",
|
|
451
|
+
humanInLoop: true
|
|
312
452
|
};
|
|
453
|
+
var DEFAULT_INTAKE = { enabled: false, fields: [], skippable: false };
|
|
313
454
|
var DEFAULT_ENDPOINTS = {
|
|
314
455
|
upload: "/ai/agent/upload-file",
|
|
315
|
-
transcribe: "/ai/agent/transcribe-audio"
|
|
456
|
+
transcribe: "/ai/agent/transcribe-audio",
|
|
457
|
+
intake: "/ai/agent/intake"
|
|
316
458
|
};
|
|
317
459
|
var DEFAULT_LAUNCHER = {
|
|
318
460
|
variant: "circle",
|
|
@@ -374,11 +516,14 @@ function resolveOptions(rawOpts) {
|
|
|
374
516
|
features: {
|
|
375
517
|
files: opts.features?.files ?? DEFAULT_FEATURES.files,
|
|
376
518
|
voice: opts.features?.voice ?? DEFAULT_FEATURES.voice,
|
|
519
|
+
humanInLoop: opts.features?.humanInLoop ?? DEFAULT_FEATURES.humanInLoop,
|
|
377
520
|
tools: opts.features?.tools
|
|
378
521
|
},
|
|
522
|
+
intake: resolveIntake(opts.intake),
|
|
379
523
|
endpoints: {
|
|
380
524
|
upload: opts.endpoints?.upload ?? DEFAULT_ENDPOINTS.upload,
|
|
381
|
-
transcribe: opts.endpoints?.transcribe ?? DEFAULT_ENDPOINTS.transcribe
|
|
525
|
+
transcribe: opts.endpoints?.transcribe ?? DEFAULT_ENDPOINTS.transcribe,
|
|
526
|
+
intake: opts.endpoints?.intake ?? DEFAULT_ENDPOINTS.intake
|
|
382
527
|
},
|
|
383
528
|
attachments: {
|
|
384
529
|
accept: opts.composer?.attachments?.accept ?? DEFAULT_ATTACHMENTS.accept,
|
|
@@ -477,6 +622,18 @@ function resolveModules(overrides) {
|
|
|
477
622
|
const byId = Object.fromEntries(list.map((m) => [m.id, m]));
|
|
478
623
|
return { list, byId };
|
|
479
624
|
}
|
|
625
|
+
function resolveIntake(overrides) {
|
|
626
|
+
const fields = (overrides?.fields ?? []).filter((f) => Boolean(f && f.name && f.label && f.type));
|
|
627
|
+
if (fields.length === 0) return DEFAULT_INTAKE;
|
|
628
|
+
return {
|
|
629
|
+
enabled: overrides?.enabled ?? false,
|
|
630
|
+
title: overrides?.title,
|
|
631
|
+
description: overrides?.description,
|
|
632
|
+
fields,
|
|
633
|
+
submitLabel: overrides?.submitLabel,
|
|
634
|
+
skippable: overrides?.skippable ?? false
|
|
635
|
+
};
|
|
636
|
+
}
|
|
480
637
|
function resolveLauncher(overrides) {
|
|
481
638
|
const callout = overrides?.callout?.text ? {
|
|
482
639
|
shape: "pill",
|
|
@@ -522,6 +679,7 @@ var SECTION_KEYS = [
|
|
|
522
679
|
"i18n",
|
|
523
680
|
"footer",
|
|
524
681
|
"features",
|
|
682
|
+
"intake",
|
|
525
683
|
"endpoints"
|
|
526
684
|
];
|
|
527
685
|
function mergeServerConfig(user, server) {
|
|
@@ -712,7 +870,7 @@ var tokens_default = ':host{--__P__-accent: __BRAND_ACCENT__;--__P__-accent-text
|
|
|
712
870
|
var reset_default = '*,*:before,*:after{box-sizing:border-box;margin:0;padding:0;border:0}button{font:inherit;color:inherit;background:none;cursor:pointer;-webkit-appearance:none;appearance:none;line-height:1}button:focus-visible,[tabindex]:focus-visible,textarea:focus-visible,input:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px}textarea,input{font:inherit;color:inherit;background:none;border:0;outline:0;resize:none}a{color:var(--__P__-accent);text-decoration:underline;text-underline-offset:2px}img,svg{display:block;max-width:100%}ul,ol{list-style:none}.__P__-app{display:block;width:100%;height:100%;font-family:var(--__P__-font);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-feature-settings:"cv11","ss01","ss03"}.__P__-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n';
|
|
713
871
|
|
|
714
872
|
// src/styles/panel.css
|
|
715
|
-
var panel_default = '.__P__-anchor{right:16px;bottom:16px}:host([data-position="bottom-left"]) .__P__-anchor,:host([data-position="top-left"]) .__P__-anchor{right:auto;left:16px}:host([data-position="top-right"]) .__P__-anchor,:host([data-position="top-left"]) .__P__-anchor{bottom:auto;top:16px}.__P__-anchor{position:fixed;display:flex;flex-direction:column;align-items:flex-end;gap:var(--__P__-space-3);pointer-events:none}.__P__-anchor{--__P__-fab-size: 56px}.__P__-anchor[data-launcher-size=sm]{--__P__-fab-size: 44px}.__P__-anchor[data-launcher-size=md]{--__P__-fab-size: 56px}.__P__-anchor[data-launcher-size=lg]{--__P__-fab-size: 68px}.__P__-anchor>*{pointer-events:auto}.__P__-fab[data-size=sm]{--__P__-fab-size: 44px;font-size:var(--__P__-text-sm)}.__P__-fab[data-size=md]{--__P__-fab-size: 56px;font-size:14px}.__P__-fab[data-size=lg]{--__P__-fab-size: 68px;font-size:var(--__P__-text-base)}.__P__-fab{display:inline-flex;align-items:center;justify-content:center;gap:var(--__P__-space-2);color:var(--__P__-accent-text);background:var(--__P__-accent);box-shadow:var(--__P__-shadow-fab);font-weight:600;line-height:1;transform-origin:bottom right;animation:__P__-fab-in var(--__P__-dur-base) var(--__P__-ease) both;transition:transform var(--__P__-dur-base) var(--__P__-ease),opacity var(--__P__-dur-base) var(--__P__-ease),box-shadow var(--__P__-dur-base) var(--__P__-ease)}.__P__-fab:hover{transform:translateY(-2px)}.__P__-fab:active{transform:translateY(0)}.__P__-fab:focus-visible{outline:2px solid var(--__P__-on-accent);outline-offset:3px}.__P__-fab svg{width:24px;height:24px;flex-shrink:0}@keyframes __P__-fab-in{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:none}}.__P__-fab[data-leaving]{position:absolute;right:0;bottom:0;animation:__P__-fab-out var(--__P__-dur-quick) var(--__P__-ease) forwards;pointer-events:none}:host([data-position^="top-"]) .__P__-fab[data-leaving]{bottom:auto;top:0}:host([data-position$="-left"]) .__P__-fab[data-leaving]{right:auto;left:0}@keyframes __P__-fab-out{0%{opacity:1;transform:none}to{opacity:0;transform:scale(.85)}}.__P__-fab[data-variant=circle]{width:var(--__P__-fab-size);height:var(--__P__-fab-size);border-radius:999px}.__P__-fab[data-variant=circle] .__P__-fab-label{display:none}.__P__-fab[data-variant=pill]{height:var(--__P__-fab-size);padding:0 18px 0 16px;border-radius:999px}.__P__-fab[data-variant=bar]{height:var(--__P__-fab-size);padding:0 22px;border-radius:var(--__P__-radius)}.__P__-fab[data-variant=minimal]{height:var(--__P__-fab-size);padding:0 var(--__P__-space-4);border-radius:999px;background:transparent;color:var(--__P__-accent);box-shadow:none;border:1px solid currentColor}.__P__-fab[data-variant=minimal]:hover{background:color-mix(in srgb,var(--__P__-accent) 12%,transparent)}.__P__-callout{--__P__-callout-fab-h: var(--__P__-fab-size, 56px);--__P__-callout-gap: clamp(12px, calc(var(--__P__-callout-fab-h) * .25), 22px);--__P__-callout-nudge-direction: -1;position:absolute;display:inline-flex;align-items:center;gap:var(--__P__-space-2);padding:10px 14px;background:var(--__P__-fg);color:var(--__P__-bg);border-radius:999px;font-size:var(--__P__-text-sm);font-weight:600;line-height:1.2;box-shadow:0 10px 30px -8px #00000059;pointer-events:auto;animation:__P__-callout-in var(--__P__-dur-slow) var(--__P__-ease);z-index:1;max-width:240px;white-space:nowrap}.__P__-callout[data-position=left]{right:calc(100% + var(--__P__-callout-gap));bottom:calc(var(--__P__-callout-fab-h) / 2);transform:translateY(50%)}.__P__-callout[data-position=right]{left:calc(100% + var(--__P__-callout-gap));bottom:calc(var(--__P__-callout-fab-h) / 2);transform:translateY(50%);--__P__-callout-nudge-direction: 1}.__P__-callout[data-position=top]{bottom:calc(100% + var(--__P__-callout-gap));right:0;max-width:min(280px,calc(100vw - 32px))}.__P__-callout[data-position=bottom]{top:calc(100% + var(--__P__-callout-gap));right:0;max-width:min(280px,calc(100vw - 32px))}:host([data-position$="-left"]) .__P__-callout[data-position=top],:host([data-position$="-left"]) .__P__-callout[data-position=bottom]{right:auto;left:0}.__P__-callout[data-shape=bubble]{border-radius:var(--__P__-radius-md);white-space:normal;width:max-content;max-width:min(280px,calc(100vw - 32px))}.__P__-callout[data-shape=callout]{padding:12px 18px;font-size:14px;background:var(--__P__-accent);color:var(--__P__-accent-text)}.__P__-callout:after{content:"";position:absolute;width:12px;height:12px;background:inherit;border-radius:2px;transform:rotate(45deg)}.__P__-callout[data-position=left]:after{right:-5px;top:50%;margin-top:-6px}.__P__-callout[data-position=right]:after{left:-5px;top:50%;margin-top:-6px}.__P__-callout[data-position=top]:after{bottom:-5px;right:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}.__P__-callout[data-position=bottom]:after{top:-5px;right:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}:host([data-position$="-left"]) .__P__-callout[data-position=top]:after,:host([data-position$="-left"]) .__P__-callout[data-position=bottom]:after{right:auto;left:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}.__P__-callout[data-animated]{animation:__P__-callout-in var(--__P__-dur-slow) var(--__P__-ease),__P__-callout-nudge 1.6s var(--__P__-ease-in-out) var(--__P__-dur-slow) infinite}@keyframes __P__-callout-in{0%{opacity:0}to{opacity:1}}@keyframes __P__-callout-nudge{0%,to{margin-left:0;margin-right:0}50%{margin-left:calc(6px * var(--__P__-callout-nudge-direction));margin-right:calc(-6px * var(--__P__-callout-nudge-direction))}}@media(prefers-reduced-motion:reduce){.__P__-callout[data-animated]{animation:__P__-callout-in 1ms var(--__P__-ease)}.__P__-icon-btn[data-recording=true],.__P__-typing span{animation:none}}.__P__-callout-close{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:inherit;opacity:.7;cursor:pointer}.__P__-callout-close:hover{opacity:1;background:#ffffff26}.__P__-callout-close svg{width:12px;height:12px}.__P__-panel{width:var(--__P__-panel-w);height:var(--__P__-panel-h);max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);background:var(--__P__-bg);color:var(--__P__-fg);border-radius:var(--__P__-radius-lg);box-shadow:var(--__P__-shadow-panel);display:flex;flex-direction:column;overflow:hidden;transform-origin:bottom right;animation:__P__-panel-in var(--__P__-dur-slow) var(--__P__-ease);border:1px solid var(--__P__-border)}:host([data-mode="open"]) .__P__-panel{width:var(--__P__-widget-w, var(--__P__-panel-w));height:var(--__P__-widget-h, var(--__P__-panel-h));min-width:var(--__P__-resize-min-w, auto);min-height:var(--__P__-resize-min-h, auto);max-width:var(--__P__-resize-max-w, calc(100vw - 32px) );max-height:var(--__P__-resize-max-h, calc(100dvh - 32px) )}@keyframes __P__-panel-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:none}}:host([data-mode="expanded"]) .__P__-panel{width:var(--__P__-expanded-w, 640px);height:var(--__P__-expanded-h, 820px);max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px)}:host([data-mode="fullscreen"]){z-index:var(--__P__-z-panel)!important}:host([data-mode="fullscreen"]) .__P__-anchor{inset:0;align-items:stretch;padding:0}:host([data-mode="fullscreen"]) .__P__-panel{width:100vw;height:100dvh;max-width:none;max-height:none;border-radius:0;border:0}:host([data-mode="fullscreen"]) .__P__-fab{display:none}:host([data-mode="inline"]) .__P__-anchor,:host([data-mode="standalone"]) .__P__-anchor{position:static;inset:auto;padding:0;align-items:stretch;width:100%;height:100%;min-height:0}:host([data-mode="inline"]) .__P__-panel,:host([data-mode="standalone"]) .__P__-panel{width:100%;height:100%;min-width:0;min-height:0;max-width:none;max-height:none;animation:none}:host([data-mode="inline"]) .__P__-fab,:host([data-mode="standalone"]) .__P__-fab{display:none}:host([data-mode="inline"]){min-height:320px}:host([data-mode="inline"]) .__P__-panel{border-radius:var(--__P__-radius)}:host([data-mode="standalone"]) .__P__-panel{border-radius:0;border:0;box-shadow:none}:host([data-mode="modal"]){position:fixed!important;inset:0!important;z-index:var(--__P__-z-panel)!important;display:block!important;width:100vw;height:100dvh;background:var(--__P__-modal-backdrop, var(--__P__-backdrop));animation:__P__-backdrop-in var(--__P__-dur-base) var(--__P__-ease) both;--__P__-panel-w: min(960px, 92vw);--__P__-panel-h: min(720px, 88dvh)}:host([data-mode="modal"]) .__P__-anchor{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:var(--__P__-space-6);pointer-events:none}:host([data-mode="modal"]) .__P__-panel{pointer-events:auto;width:var(--__P__-widget-w, var(--__P__-panel-w));height:var(--__P__-widget-h, var(--__P__-panel-h));max-width:calc(100vw - 48px);max-height:calc(100dvh - 48px);min-width:0;min-height:0;border-radius:var(--__P__-radius);box-shadow:var(--__P__-shadow-panel);animation:__P__-modal-in var(--__P__-dur-base) var(--__P__-ease);translate:var(--__P__-modal-dx, 0px) var(--__P__-modal-dy, 0px)}:host([data-mode="modal"]) .__P__-header,:host([data-mode="modal"]) .__P__-back-header,:host([data-mode="modal"]) .__P__-home-hero{cursor:grab;touch-action:none}:host([data-mode="modal"]) .__P__-panel[data-dragging]{cursor:grabbing;user-select:none}:host([data-mode="modal"]) .__P__-panel[data-dragging] *{cursor:grabbing}:host([data-mode="modal"]) .__P__-fab{display:none}@keyframes __P__-backdrop-in{0%{background:#0000}to{background:var(--__P__-modal-backdrop, var(--__P__-backdrop))}}@keyframes __P__-modal-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}:host([data-mode="drawer"]){--__P__-panel-w: min(440px, calc(100vw - 32px) );--__P__-panel-h: 100dvh}:host([data-mode="drawer"]) .__P__-anchor{position:fixed;--__P__-inset-x: var(--__P__-panel-inset, 12px);--__P__-inset-y: var(--__P__-panel-inset, 3dvh);top:var(--__P__-inset-y);bottom:auto;right:var(--__P__-inset-x);left:auto;width:min(var(--__P__-widget-w, var(--__P__-panel-w)),calc(100vw - var(--__P__-inset-x) * 2));height:min(var(--__P__-widget-h, var(--__P__-panel-h)),calc(100dvh - var(--__P__-inset-y) * 2));padding:0;display:block;pointer-events:auto}:host([data-mode="drawer"][data-position$="-left"]) .__P__-anchor{right:auto;left:var(--__P__-inset-x)}:host([data-mode="drawer"][data-position^="bottom-"]) .__P__-anchor{top:auto;bottom:var(--__P__-inset-y)}:host([data-mode="drawer"]) .__P__-panel{width:100%;height:100%;max-width:none;max-height:none;min-width:0;min-height:0;border-radius:var(--__P__-radius, 12px);border:1px solid var(--__P__-border);box-shadow:-8px 16px 32px -12px #00000038;animation:__P__-drawer-in var(--__P__-dur-base) var(--__P__-ease)}:host([data-mode="drawer"][data-position$="-left"]) .__P__-panel{box-shadow:8px 16px 32px -12px #00000038;animation:__P__-drawer-in-left var(--__P__-dur-base) var(--__P__-ease)}.__P__-fab[data-edge-tab]{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--__P__-space-2);position:fixed;top:50%;height:140px;width:auto;min-width:0;padding:10px 8px;writing-mode:vertical-rl;text-orientation:mixed;transform:translateY(-50%);transform-origin:center;animation:__P__-edge-tab-in var(--__P__-dur-base) var(--__P__-ease) both}.__P__-fab[data-edge-tab] svg{writing-mode:horizontal-tb}.__P__-fab[data-edge-tab]:hover{transform:translateY(-50%) scale(1.03)}.__P__-fab[data-edge-tab]:active{transform:translateY(-50%) scale(.97)}:host([data-position$="-right"]) .__P__-fab[data-edge-tab]{right:0;left:auto;border-radius:12px 0 0 12px;box-shadow:-6px 0 18px -8px #0000004d}:host([data-position$="-left"]) .__P__-fab[data-edge-tab]{left:0;right:auto;border-radius:0 12px 12px 0;box-shadow:6px 0 18px -8px #0000004d}.__P__-fab[data-edge-tab][data-leaving]{position:fixed;top:50%;bottom:auto;animation:__P__-edge-tab-out var(--__P__-dur-quick) var(--__P__-ease) forwards}@keyframes __P__-edge-tab-in{0%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:1;transform:translateY(-50%) scale(1)}}@keyframes __P__-edge-tab-out{0%{opacity:1;transform:translateY(-50%) scale(1)}to{opacity:0;transform:translateY(-50%) scale(.85)}}@keyframes __P__-drawer-in{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes __P__-drawer-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}@media(prefers-reduced-motion:reduce){:host([data-mode="drawer"]) .__P__-panel,.__P__-fab[data-edge-tab]{animation:none}}.__P__-header{display:flex;align-items:center;gap:var(--__P__-space-2);padding:10px 12px;border-bottom:1px solid var(--__P__-border);background:var(--__P__-bg)}.__P__-header h1{font-size:14px;font-weight:600;flex:1;letter-spacing:-.01em}.__P__-header-actions{margin-left:auto;display:flex;align-items:center;gap:var(--__P__-space-1);flex-shrink:0}.__P__-agent{flex:1;display:inline-flex;align-items:center;gap:10px;min-width:0}.__P__-agent-avatar{position:relative;width:32px;height:32px;border-radius:999px;background:var(--__P__-bg-elevated);color:var(--__P__-fg-muted);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--__P__-text-xs);overflow:hidden;flex-shrink:0}.__P__-agent-avatar img{width:100%;height:100%;object-fit:cover}.__P__-agent-avatar:after{content:"";position:absolute;right:-1px;bottom:-1px;width:10px;height:10px;border-radius:999px;border:2px solid var(--__P__-bg);background:var(--__P__-neutral)}.__P__-agent-avatar[data-status=online]:after{background:var(--__P__-success)}.__P__-agent-avatar[data-status=away]:after{background:var(--__P__-warning)}.__P__-agent-avatar[data-status=offline]:after{background:var(--__P__-neutral)}.__P__-agent-meta{display:flex;flex-direction:column;line-height:1.15;min-width:0}.__P__-agent-meta strong{font-size:14px;font-weight:600;letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-agent-meta span{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-suggestions{display:flex;flex-wrap:nowrap;gap:var(--__P__-space-2);padding:6px 14px 10px;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scroll-snap-type:x proximity;scrollbar-width:none;-ms-overflow-style:none;min-width:0}.__P__-suggestions::-webkit-scrollbar{display:none}.__P__-suggestions:before,.__P__-suggestions:after{content:"";flex:1 1 0;min-width:0}.__P__-suggestion{flex:0 0 auto;scroll-snap-align:center;padding:7px 14px;border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);color:var(--__P__-fg);font-size:var(--__P__-text-sm);font-weight:500;white-space:nowrap;transition:background var(--__P__-dur-quick) var(--__P__-ease),border-color var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease)}.__P__-suggestion:hover{border-color:var(--__P__-accent);color:var(--__P__-accent);transform:translateY(-1px)}.__P__-suggestion:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px;border-color:var(--__P__-accent)}.__P__-suggestion:active{transform:translateY(0)}.__P__-icon-btn{width:32px;height:32px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted);transition:background var(--__P__-dur-quick) var(--__P__-ease),color var(--__P__-dur-quick) var(--__P__-ease)}.__P__-icon-btn:hover{background:var(--__P__-bg-elevated);color:var(--__P__-fg)}.__P__-icon-btn:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-icon-btn:active{background:var(--__P__-border)}.__P__-icon-btn:disabled{opacity:.45;cursor:not-allowed}.__P__-icon-btn:before{content:"";position:absolute;inset:-6px}.__P__-icon-btn{position:relative}.__P__-icon-btn svg{width:18px;height:18px}.__P__-icon-btn[data-recording=true]{color:var(--__P__-accent);background:color-mix(in srgb,var(--__P__-accent) 12%,transparent);animation:__P__-pulse 1.2s var(--__P__-ease) infinite}@keyframes __P__-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--__P__-accent) 40%,transparent)}50%{box-shadow:0 0 0 6px color-mix(in srgb,var(--__P__-accent) 0%,transparent)}}.__P__-list-wrap{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}.__P__-jump{position:absolute;right:14px;bottom:14px;z-index:2;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:999px;border:1px solid var(--__P__-border);background:var(--__P__-bg-elevated);color:var(--__P__-fg);box-shadow:var(--__P__-shadow-panel);cursor:pointer;opacity:.85;transition:opacity var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease);animation:__P__-bubble-in var(--__P__-dur-base) var(--__P__-ease)}.__P__-jump:hover{opacity:1}.__P__-jump:active{transform:translateY(1px)}.__P__-jump svg{width:18px;height:18px}.__P__-list{flex:1;min-height:0;overflow-y:auto;padding:var(--__P__-space-4);padding-bottom:var(--__P__-space-8);display:flex;flex-direction:column;gap:14px;scrollbar-width:thin;scrollbar-color:var(--__P__-border-strong) transparent;scrollbar-gutter:stable}.__P__-list::-webkit-scrollbar{width:8px}.__P__-list::-webkit-scrollbar-thumb{background:var(--__P__-border-strong);border-radius:8px}.__P__-date-divider{position:sticky;top:var(--__P__-space-2);z-index:2;display:flex;justify-content:center;margin:var(--__P__-space-1) 0;pointer-events:none}.__P__-date-pill{padding:3px 10px;border-radius:999px;font-size:11px;font-weight:600;color:var(--__P__-fg-muted);background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);box-shadow:var(--__P__-shadow-card);opacity:0;pointer-events:none;transition:opacity var(--__P__-dur-base) var(--__P__-ease)}.__P__-list[data-scrolling=true] .__P__-date-pill{opacity:1;pointer-events:auto}@media(prefers-reduced-motion:reduce){.__P__-date-pill{transition:none}}.__P__-bubble-row{display:flex}.__P__-bubble-row[data-role=user]{justify-content:flex-end}.__P__-bubble-row[data-role=assistant]{justify-content:flex-start}.__P__-bubble{max-width:100%;padding:var(--__P__-space-3) var(--__P__-space-4);border-radius:var(--__P__-radius);line-height:1.6;font-size:14px;word-wrap:break-word;overflow-wrap:anywhere;box-shadow:0 1px 2px #0000000a,0 1px 8px -4px #0000000f;animation:__P__-bubble-in var(--__P__-dur-base) var(--__P__-ease)}.__P__-bubble ::selection{background:color-mix(in srgb,var(--__P__-accent) 30%,transparent)}.__P__-bubble-row[data-role=user] .__P__-bubble ::selection{background:#fff6;color:var(--__P__-bubble-user-text)}@keyframes __P__-bubble-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.__P__-bubble-row[data-role=user] .__P__-bubble{background:var(--__P__-bubble-user);color:var(--__P__-bubble-user-text);border-bottom-right-radius:5px}.__P__-bubble-row[data-role=assistant] .__P__-bubble{background:var(--__P__-bubble-assistant);color:var(--__P__-bubble-assistant-text);border-bottom-left-radius:5px}.__P__-bubble-col{display:flex;flex-direction:column;max-width:85%;min-width:0}.__P__-bubble-row[data-role=user] .__P__-bubble-col{align-items:flex-end}.__P__-bubble-row[data-role=assistant] .__P__-bubble-col{align-items:flex-start}.__P__-bubble-time{margin-top:3px;padding:0 4px;font-size:11px;line-height:1;color:var(--__P__-fg-muted);user-select:none}.__P__-md>*:first-child{margin-top:0}.__P__-md>*:last-child{margin-bottom:0}.__P__-md p{margin:10px 0}.__P__-md h1,.__P__-md h2,.__P__-md h3,.__P__-md h4,.__P__-md h5,.__P__-md h6{margin:18px 0 8px;line-height:1.3;letter-spacing:-.01em;font-weight:700}.__P__-md h1{font-size:1.4em}.__P__-md h2{font-size:1.22em}.__P__-md h3{font-size:1.08em}.__P__-md h4,.__P__-md h5,.__P__-md h6{font-size:1em}.__P__-md>h1:first-child,.__P__-md>h2:first-child,.__P__-md>h3:first-child,.__P__-md>h4:first-child,.__P__-md>h5:first-child,.__P__-md>h6:first-child{margin-top:0}.__P__-md ul,.__P__-md ol{padding-left:1.5em;margin:10px 0}.__P__-md ul{list-style:disc}.__P__-md ol{list-style:decimal}.__P__-md li{margin:6px 0;padding-left:2px}.__P__-md li::marker{color:var(--__P__-fg-muted)}.__P__-md li>p{margin:6px 0}.__P__-md li>ul,.__P__-md li>ol{margin:6px 0}.__P__-md strong,.__P__-md b{font-weight:650;letter-spacing:-.005em}.__P__-md em,.__P__-md i{font-style:italic}.__P__-md code{font-family:var(--__P__-font-mono);font-size:.86em;padding:1px 6px;border-radius:5px;background:color-mix(in srgb,var(--__P__-accent) 10%,transparent);color:var(--__P__-fg);border:1px solid color-mix(in srgb,var(--__P__-accent) 16%,transparent)}.__P__-md pre{font-family:var(--__P__-font-mono);font-size:12.5px;padding:12px 14px;border-radius:var(--__P__-radius-sm);background:#7f7f7f1f;overflow-x:auto;margin:var(--__P__-space-3) 0;line-height:1.5}.__P__-md pre code{padding:0;background:none}.__P__-md a{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px}.__P__-md a:hover{text-decoration-thickness:2px}.__P__-md blockquote{margin:14px 0;padding:6px 14px;border-left:3px solid color-mix(in srgb,var(--__P__-accent) 50%,transparent);background:color-mix(in srgb,var(--__P__-accent) 5%,transparent);border-radius:0 var(--__P__-radius-sm) var(--__P__-radius-sm) 0;color:var(--__P__-fg-muted)}.__P__-md blockquote>:first-child{margin-top:0}.__P__-md blockquote>:last-child{margin-bottom:0}.__P__-md hr{border:0;height:1px;background:color-mix(in srgb,currentColor 18%,transparent);margin:var(--__P__-space-4) 0}.__P__-md table{border-collapse:collapse;margin:var(--__P__-space-3) 0;font-size:.95em;display:block;overflow-x:auto;max-width:100%;font-variant-numeric:tabular-nums}.__P__-md th,.__P__-md td{padding:6px 10px;border-bottom:1px solid color-mix(in srgb,currentColor 12%,transparent);text-align:left}.__P__-md th{font-weight:700;background:color-mix(in srgb,currentColor 6%,transparent)}.__P__-md h1+ul,.__P__-md h1+ol,.__P__-md h2+ul,.__P__-md h2+ol,.__P__-md h3+ul,.__P__-md h3+ol,.__P__-md h4+ul,.__P__-md h4+ol{margin-top:var(--__P__-space-1)}.__P__-loading{display:inline-flex;align-items:center;gap:var(--__P__-space-2);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm)}.__P__-loading-spinner{width:14px;height:14px;border-radius:999px;border:2px solid currentColor;border-top-color:transparent;animation:__P__-spin .8s linear infinite}@keyframes __P__-spin{to{transform:rotate(1turn)}}.__P__-typing{display:inline-flex;gap:var(--__P__-space-1);padding:var(--__P__-space-1) 0}.__P__-typing span{width:5px;height:5px;border-radius:999px;background:currentColor;opacity:.4;animation:__P__-blink 1.2s var(--__P__-ease) infinite}.__P__-typing span:nth-child(2){animation-delay:.2s}.__P__-typing span:nth-child(3){animation-delay:.4s}@keyframes __P__-blink{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-2px)}}.__P__-reasoning{margin:var(--__P__-space-1) 0 var(--__P__-space-2);padding-left:var(--__P__-space-3);border-left:2px solid var(--__P__-border-strong)}.__P__-reasoning-summary{display:inline-flex;align-items:center;gap:var(--__P__-space-1);cursor:pointer;list-style:none;user-select:none;color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600}.__P__-reasoning-summary::-webkit-details-marker{display:none}.__P__-reasoning-summary:before{content:"";width:5px;height:5px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);opacity:.7;transition:transform var(--__P__-dur-quick) var(--__P__-ease)}.__P__-reasoning[open] .__P__-reasoning-summary:before{transform:rotate(45deg)}.__P__-reasoning[data-active=true] .__P__-reasoning-label{animation:__P__-reasoning-pulse 1.4s var(--__P__-ease) infinite}@keyframes __P__-reasoning-pulse{0%,to{opacity:.5}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.__P__-reasoning[data-active=true] .__P__-reasoning-label{animation:none}}.__P__-reasoning-body{margin-top:var(--__P__-space-1);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm)}.__P__-reasoning-body>:first-child{margin-top:0}.__P__-reasoning-body>:last-child{margin-bottom:0}.__P__-tool-chip{display:inline-flex;align-items:center;gap:6px;padding:var(--__P__-space-1) var(--__P__-space-2);margin-top:6px;border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs)}.__P__-composer{border-top:1px solid var(--__P__-border);padding:10px 12px;background:var(--__P__-bg);display:flex;flex-direction:column;gap:var(--__P__-space-2)}.__P__-composer-row{display:flex;align-items:flex-end;gap:6px}.__P__-textarea{flex:1;height:40px;max-height:160px;padding:10px 12px;border-radius:var(--__P__-radius);background:var(--__P__-bg-elevated);border:1px solid transparent;font-size:14px;line-height:1.4;transition:height var(--__P__-dur-quick) var(--__P__-ease),border-color var(--__P__-dur-quick) var(--__P__-ease),box-shadow var(--__P__-dur-quick) var(--__P__-ease)}.__P__-textarea:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:1px;border-color:var(--__P__-focus)}@media(pointer:coarse){.__P__-textarea,.__P__-home-search-input{font-size:16px}.__P__-textarea{height:44px}}.__P__-send{width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;transition:opacity var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease),background var(--__P__-dur-quick) var(--__P__-ease)}.__P__-send[data-shape=circle]{border-radius:999px}.__P__-send[data-shape=square]{border-radius:var(--__P__-radius-sm)}.__P__-send[data-shape=pill]{width:auto;padding:0 18px;border-radius:999px}.__P__-send[data-variant=filled]{background:var(--__P__-accent);color:var(--__P__-accent-text)}.__P__-send[data-variant=outline]{background:transparent;color:var(--__P__-accent);border-color:var(--__P__-accent)}.__P__-send[data-variant=outline]:not(:disabled):hover{background:color-mix(in srgb,var(--__P__-accent) 10%,transparent)}.__P__-send[data-variant=ghost]{background:transparent;color:var(--__P__-accent)}.__P__-send[data-variant=ghost]:not(:disabled):hover{background:color-mix(in srgb,var(--__P__-accent) 8%,transparent)}.__P__-send:disabled{opacity:.4;cursor:not-allowed}.__P__-send:not(:disabled):hover{transform:translateY(-1px)}.__P__-send:not(:disabled):active{transform:translateY(0)}.__P__-send:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-send svg{width:18px;height:18px}.__P__-composer-actions{display:flex;gap:var(--__P__-space-1);flex-wrap:wrap}.__P__-attachments{display:flex;flex-wrap:wrap;gap:6px}.__P__-attachment-chip{display:inline-flex;align-items:center;gap:6px;padding:var(--__P__-space-1) var(--__P__-space-2) var(--__P__-space-1) var(--__P__-space-1);border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);font-size:var(--__P__-text-xs);max-width:200px}.__P__-attachment-thumb{width:24px;height:24px;border-radius:999px;object-fit:cover;background:var(--__P__-border)}.__P__-attachment-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__P__-attachment-remove{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted)}.__P__-attachment-remove:hover{background:var(--__P__-border);color:var(--__P__-fg)}.__P__-dropzone{position:absolute;inset:8px;border:2px dashed var(--__P__-accent);border-radius:var(--__P__-radius);background:color-mix(in srgb,var(--__P__-accent) 8%,transparent);display:flex;align-items:center;justify-content:center;font-weight:600;color:var(--__P__-accent);pointer-events:none;z-index:10;animation:__P__-fade-in var(--__P__-dur-quick) var(--__P__-ease)}@keyframes __P__-fade-in{0%{opacity:0}to{opacity:1}}.__P__-error{margin-top:var(--__P__-space-1);padding:8px 10px;border-radius:var(--__P__-radius-sm);background:var(--__P__-danger-bg);color:var(--__P__-danger-text);font-size:var(--__P__-text-sm);display:flex;align-items:center;gap:var(--__P__-space-2)}.__P__-error button{color:inherit;text-decoration:underline;font-size:var(--__P__-text-sm)}.__P__-history{flex:1;overflow-y:auto;padding:var(--__P__-space-2) var(--__P__-space-1) var(--__P__-space-3)}.__P__-history-footer{flex:none;padding:var(--__P__-space-2) var(--__P__-space-3) var(--__P__-space-3);border-top:1px solid var(--__P__-border);background:var(--__P__-surface)}.__P__-history-new{width:100%;display:flex;align-items:center;justify-content:center;gap:var(--__P__-space-2);padding:var(--__P__-space-2) var(--__P__-space-3);border:none;border-radius:var(--__P__-radius-md);background:var(--__P__-accent);color:var(--__P__-on-accent);cursor:pointer;font-size:var(--__P__-text-sm);font-weight:600;transition:filter var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-history-new svg{width:16px;height:16px}.__P__-history-new:hover{filter:brightness(1.08)}.__P__-history-new:active{transform:translateY(1px)}.__P__-history-new:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-history-empty{flex:1;display:flex;align-items:center;justify-content:center;padding:40px 16px;color:var(--__P__-fg-muted);font-size:14px;text-align:center}.__P__-history-group{display:flex;flex-direction:column;padding:0 var(--__P__-space-2)}.__P__-history-heading{font-size:var(--__P__-text-xs);font-weight:600;color:var(--__P__-fg-muted);padding:12px 8px 6px;text-transform:uppercase;letter-spacing:.04em}.__P__-history-item{all:unset;display:flex;flex-direction:column;gap:3px;padding:10px 12px;border-radius:var(--__P__-radius-md);cursor:pointer;transition:background var(--__P__-dur-base) var(--__P__-ease)}.__P__-history-item:hover{background:var(--__P__-bg-elevated)}.__P__-history-item:focus-visible{background:var(--__P__-bg-elevated);outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-history-title{font-size:14px;font-weight:500;color:var(--__P__-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-history-preview{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-history-item[data-closed=true] .__P__-history-title:after{content:"\\2022";margin-left:var(--__P__-space-2);opacity:.5}.__P__-list-loading{margin:auto;padding:var(--__P__-space-6) var(--__P__-space-4);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);text-align:center}.__P__-readonly-banner{display:flex;flex-direction:column;align-items:center;gap:10px;padding:14px 12px;margin:0 var(--__P__-space-3) var(--__P__-space-3);border-radius:var(--__P__-radius-md);background:var(--__P__-bg-elevated);color:var(--__P__-fg-muted);text-align:center;font-size:var(--__P__-text-sm)}.__P__-readonly-label{line-height:1.4}.__P__-readonly-cta{appearance:none;border:0;cursor:pointer;padding:var(--__P__-space-2) var(--__P__-space-4);border-radius:999px;background:var(--__P__-accent);color:var(--__P__-accent-text, #fff);font:inherit;font-weight:600;font-size:var(--__P__-text-sm);transition:filter var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-readonly-cta:hover,.__P__-readonly-cta:focus-visible{filter:brightness(1.1)}.__P__-readonly-cta:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px}.__P__-composer-footer{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:10px 16px;margin:0 var(--__P__-space-3);border-top:1px solid var(--__P__-border);text-align:center;font-size:11px;line-height:1.4;color:var(--__P__-fg-muted)}.__P__-disclaimer{max-width:320px;margin:0 auto;opacity:.9;letter-spacing:.01em}.__P__-poweredby{display:inline-flex;align-items:center;justify-content:center;gap:6px;color:inherit;text-decoration:none;opacity:.7;transition:opacity var(--__P__-dur-base) var(--__P__-ease);font-size:11px;letter-spacing:.02em}.__P__-poweredby:hover{opacity:1}.__P__-poweredby-logo{height:12px;width:auto;display:inline-block;vertical-align:middle}.__P__-poweredby-bar{flex:none;display:flex;align-items:center;justify-content:center;padding:6px 16px;border-top:1px solid var(--__P__-border);background:var(--__P__-bg-elevated)}.__P__-menu-wrap{position:relative;display:inline-flex}.__P__-menu{position:absolute;top:100%;right:0;margin-top:6px;min-width:200px;padding:6px;background:var(--__P__-bg);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);box-shadow:var(--__P__-shadow-panel);z-index:10;display:flex;flex-direction:column;gap:2px;animation:__P__-menu-in var(--__P__-dur-base) var(--__P__-ease)}@media(prefers-reduced-motion:reduce){.__P__-menu{animation:none}}@keyframes __P__-menu-in{0%{opacity:0;transform:translateY(-4px) scale(.98);transform-origin:top right}to{opacity:1;transform:none}}.__P__-menu-item{all:unset;display:flex;align-items:center;gap:10px;padding:8px 10px;font-size:var(--__P__-text-sm);color:var(--__P__-fg);border-radius:var(--__P__-radius-sm);cursor:pointer;user-select:none}.__P__-menu-item:hover{background:var(--__P__-bg-elevated)}.__P__-menu-item:focus-visible{background:var(--__P__-bg-elevated);outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-menu-item[disabled]{opacity:.45;cursor:not-allowed}.__P__-menu-icon{display:inline-flex;width:16px;height:16px;color:var(--__P__-fg-muted)}.__P__-menu-icon svg{width:16px;height:16px}.__P__-menu-label{flex:1}.__P__-menu-check{display:inline-flex;color:var(--__P__-accent)}.__P__-menu-check svg{width:14px;height:14px}.__P__-resize-grip{position:absolute;width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted);opacity:.45;transition:opacity var(--__P__-dur-base) var(--__P__-ease);z-index:2;touch-action:none;user-select:none}.__P__-resize-grip:hover,.__P__-resize-grip:focus-visible{opacity:1}.__P__-resize-grip svg{width:10px;height:10px}.__P__-resize-grip--bottom-left{bottom:2px;left:2px;cursor:nesw-resize;transform:scaleX(-1)}.__P__-resize-grip--bottom-right{bottom:2px;right:2px;cursor:nwse-resize}.__P__-resize-grip--top-left{top:2px;left:2px;cursor:nwse-resize;transform:rotate(180deg)}.__P__-resize-grip--top-right{top:2px;right:2px;cursor:nesw-resize;transform:scaleY(-1)}:host(:not([data-mode="open"])) .__P__-resize-grip{display:none}.__P__-messenger{display:flex;flex-direction:column;overflow:hidden}.__P__-messenger-body{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}.__P__-module{display:flex;flex-direction:column;height:100%;min-height:0}.__P__-module-scroll{flex:1;min-height:0;overflow-y:auto;padding:var(--__P__-space-3);display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-home{background:radial-gradient(125% 65% at 88% 0%,color-mix(in srgb,#fff 16%,transparent),transparent 55%),linear-gradient(180deg,var(--__P__-accent) 0%,var(--__P__-accent) 22%,color-mix(in srgb,var(--__P__-accent) 28%,var(--__P__-surface)) 44%,var(--__P__-surface) 70%);border-radius:var(--__P__-radius-lg) var(--__P__-radius-lg) 0 0}.__P__-home-scroll{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;background:transparent}.__P__-home-cards{display:flex;flex-direction:column;gap:var(--__P__-space-3);padding:4px 14px 16px}.__P__-module-pad{padding:var(--__P__-space-3) var(--__P__-space-3) 0}.__P__-module-empty{display:flex;flex-direction:column;align-items:center;gap:var(--__P__-space-3);padding:var(--__P__-space-8) var(--__P__-space-4);text-align:center;color:var(--__P__-fg-muted);font-size:var(--__P__-text-base)}.__P__-module-retry{padding:var(--__P__-space-2) var(--__P__-space-4);border:1px solid var(--__P__-border-strong);border-radius:var(--__P__-radius-sm);color:var(--__P__-fg);font-weight:600;cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out),border-color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-module-retry:hover{background:var(--__P__-hover);border-color:var(--__P__-accent)}.__P__-module-retry:active{background:var(--__P__-border)}.__P__-module-retry:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-help-list{flex:1;min-height:0;overflow-y:auto;padding-bottom:var(--__P__-space-3)}.__P__-help-group{display:flex;flex-direction:column}.__P__-help-section-title{position:sticky;top:0;z-index:1;margin:0;padding:var(--__P__-space-3) var(--__P__-space-5) var(--__P__-space-2);font-size:var(--__P__-text-xs);font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--__P__-fg-muted);background:var(--__P__-bg)}.__P__-help-card{margin:0 var(--__P__-space-3) var(--__P__-space-3);background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);overflow:hidden}.__P__-help-card .__P__-list-row{border-bottom:0;border-radius:0}.__P__-help-card .__P__-list-row+.__P__-list-row{border-top:1px solid var(--__P__-border)}.__P__-help-card .__P__-list-row:hover{background:var(--__P__-hover)}.__P__-module-cta{padding:var(--__P__-space-3);border-top:1px solid var(--__P__-border)}.__P__-tabbar{display:flex;border-top:1px solid var(--__P__-border);background:var(--__P__-bg-elevated);flex-shrink:0}.__P__-tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--__P__-space-1);min-height:48px;padding:var(--__P__-space-2) var(--__P__-space-1);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600;transition:color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-tab:hover{color:var(--__P__-fg)}.__P__-tab[aria-selected=true]{color:var(--__P__-accent)}.__P__-tab:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-tab:active{background:var(--__P__-hover)}.__P__-tab-icon{position:relative;display:inline-flex}.__P__-tab-icon svg{width:22px;height:22px}.__P__-tab-badge{position:absolute;top:-4px;left:calc(50% + 6px);min-width:16px;height:16px;padding:0 4px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:var(--__P__-accent);color:var(--__P__-on-accent);font-size:10px;font-weight:600;line-height:1}.__P__-home-hero{flex-shrink:0;padding:var(--__P__-space-5) var(--__P__-space-5) var(--__P__-space-3);color:var(--__P__-on-accent);--__P__-focus: var(--__P__-on-accent)}.__P__-home-hero-top{display:flex;align-items:center;justify-content:space-between;gap:var(--__P__-space-3);min-height:32px}.__P__-home-brand{font-size:14px;font-weight:600;letter-spacing:.01em;color:color-mix(in srgb,#fff 82%,transparent);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.__P__-home-brand-spacer{flex:1}.__P__-home-hero-actions{display:flex;align-items:center;gap:var(--__P__-space-2);flex-shrink:0}.__P__-home-hero-actions .__P__-icon-btn{color:#fff}.__P__-home-greeting{margin:28px 0 0;font-family:var(--__P__-font-display);font-size:var(--__P__-text-2xl);font-weight:800;line-height:1.18;letter-spacing:-.01em;overflow-wrap:anywhere}.__P__-home-lead{margin:2px 0 0;font-family:var(--__P__-font-display);font-size:var(--__P__-text-2xl);font-weight:800;line-height:1.18;letter-spacing:-.01em;color:color-mix(in srgb,var(--__P__-on-accent) 88%,transparent);overflow-wrap:anywhere}.__P__-home-avatars{display:flex}.__P__-home-avatar{width:30px;height:30px;border-radius:999px;overflow:hidden;margin-left:-10px;border:2px solid color-mix(in srgb,#fff 92%,transparent);box-shadow:0 1px 3px #0000002e;background:var(--__P__-surface);display:inline-flex;align-items:center;justify-content:center;font-size:var(--__P__-text-xs);font-weight:700;color:var(--__P__-fg)}.__P__-home-avatar:first-child{margin-left:0}.__P__-home-avatar img{width:100%;height:100%;object-fit:cover}.__P__-home-content{background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);box-shadow:var(--__P__-shadow-card);overflow:hidden}.__P__-home-content-title{padding:var(--__P__-space-4) var(--__P__-space-4) var(--__P__-space-3);font-size:var(--__P__-text-sm);font-weight:700}.__P__-home-content-list{display:flex;flex-direction:column;padding:0 var(--__P__-space-2) var(--__P__-space-2)}.__P__-home-content-list .__P__-list-row+.__P__-list-row{border-top:1px solid var(--__P__-border)}.__P__-home-card{display:block;width:100%;text-align:left;background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);padding:var(--__P__-space-4);box-shadow:var(--__P__-shadow-card)}.__P__-home-card[data-interactive=true]{cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-home-card[data-interactive=true]:hover{background:var(--__P__-bg-elevated)}.__P__-home-card[data-interactive=true]:active{transform:translateY(1px)}.__P__-home-card[data-interactive=true]:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-home-recent-row{display:flex;align-items:center;gap:var(--__P__-space-3)}.__P__-home-recent-avatar{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;flex-shrink:0;border-radius:999px;background:color-mix(in oklch,var(--__P__-accent) 14%,transparent);color:var(--__P__-accent)}.__P__-home-recent-avatar svg{width:20px;height:20px}.__P__-home-recent-body{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}.__P__-home-recent-title{font-weight:600;font-size:14px}.__P__-home-recent-preview{color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__P__-home-recent-at{color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);flex-shrink:0}.__P__-home-recent-dot{width:8px;height:8px;border-radius:999px;background:var(--__P__-accent);flex-shrink:0}.__P__-home-recent-row[data-unread=true] .__P__-home-recent-title{font-weight:700}.__P__-home-status{display:flex;align-items:center;gap:var(--__P__-space-3)}.__P__-home-status-icon svg{width:22px;height:22px;color:var(--__P__-success)}.__P__-home-status[data-level=degraded] .__P__-home-status-icon svg{color:var(--__P__-warning)}.__P__-home-status[data-level=down] .__P__-home-status-icon svg{color:var(--__P__-danger)}.__P__-home-status-text{font-weight:600;font-size:14px}.__P__-home-search{display:flex;align-items:center;gap:var(--__P__-space-2);width:100%;padding:var(--__P__-space-3) var(--__P__-space-4);border-radius:var(--__P__-radius);border:1px solid var(--__P__-border);background:var(--__P__-surface);text-align:left}.__P__-home-search[data-input=true]{background:var(--__P__-bg-elevated)}.__P__-home-search:hover{border-color:var(--__P__-border-strong)}.__P__-home-search:focus-visible,.__P__-home-search:focus-within{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-home-search-text{flex:1;color:var(--__P__-fg-muted);font-size:14px}.__P__-home-search-input{flex:1;border:0;background:transparent;font-size:14px;color:var(--__P__-fg);outline:none}.__P__-home-search-icon svg{width:18px;height:18px;color:var(--__P__-accent)}.__P__-list-row{display:flex;align-items:center;gap:var(--__P__-space-3);width:100%;min-height:44px;text-align:left;padding:var(--__P__-space-3) var(--__P__-space-2);border-radius:var(--__P__-radius-sm)}.__P__-list-row:hover{background:var(--__P__-bg-elevated)}.__P__-list-row:active{background:var(--__P__-border)}.__P__-list-row:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-list-row-body{display:flex;flex-direction:column;min-width:0;flex:1}.__P__-list-row-title{font-weight:600;font-size:var(--__P__-text-md);line-height:1.35}.__P__-list-row-sub{color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);margin-top:var(--__P__-space-1);line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.__P__-list-row-chevron svg{width:18px;height:18px;color:var(--__P__-accent);flex-shrink:0}.__P__-back-header{display:flex;align-items:center;gap:var(--__P__-space-2);padding:10px 12px;border-bottom:1px solid var(--__P__-border);flex-shrink:0}.__P__-back-title{flex:1;text-align:center;font-size:var(--__P__-text-md);font-weight:700;margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-back-spacer{width:32px;height:1px}.__P__-content{display:flex;flex-direction:column;gap:14px;width:100%;max-width:68ch;margin:0 auto}.__P__-content-hero{width:100%;border-radius:var(--__P__-radius)}.__P__-content-subtitle{color:var(--__P__-fg-muted);margin:0}.__P__-content-frame{flex:1;min-height:0;width:100%;border:0;background:#fff}.__P__-news-list{display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-news-card{display:block;width:100%;text-align:left;border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);overflow:hidden;background:var(--__P__-surface)}.__P__-news-card{transition:background var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-news-card:hover{background:var(--__P__-bg-elevated)}.__P__-news-card:active{transform:translateY(1px)}.__P__-news-card:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-news-hero{width:100%;display:block}.__P__-news-body{display:flex;flex-direction:column;gap:6px;padding:14px 16px}.__P__-news-tags{display:flex;gap:6px;flex-wrap:wrap}.__P__-news-tag{font-size:var(--__P__-text-xs);font-weight:600;color:var(--__P__-accent);background:color-mix(in srgb,var(--__P__-accent) 12%,transparent);padding:2px 8px;border-radius:999px}.__P__-news-title{font-weight:700;font-size:var(--__P__-text-md)}.__P__-news-summary{color:var(--__P__-fg-muted);font-size:14px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.__P__-modules-empty{display:flex;align-items:center;justify-content:center;position:relative}.__P__-modules-empty-close{position:absolute;top:12px;right:12px}.__P__-modules-empty-text{color:var(--__P__-fg-muted);font-size:var(--__P__-text-base)}\n';
|
|
873
|
+
var panel_default = '.__P__-anchor{right:16px;bottom:16px}:host([data-position="bottom-left"]) .__P__-anchor,:host([data-position="top-left"]) .__P__-anchor{right:auto;left:16px}:host([data-position="top-right"]) .__P__-anchor,:host([data-position="top-left"]) .__P__-anchor{bottom:auto;top:16px}.__P__-anchor{position:fixed;display:flex;flex-direction:column;align-items:flex-end;gap:var(--__P__-space-3);pointer-events:none}.__P__-anchor{--__P__-fab-size: 56px}.__P__-anchor[data-launcher-size=sm]{--__P__-fab-size: 44px}.__P__-anchor[data-launcher-size=md]{--__P__-fab-size: 56px}.__P__-anchor[data-launcher-size=lg]{--__P__-fab-size: 68px}.__P__-anchor>*{pointer-events:auto}.__P__-fab[data-size=sm]{--__P__-fab-size: 44px;font-size:var(--__P__-text-sm)}.__P__-fab[data-size=md]{--__P__-fab-size: 56px;font-size:14px}.__P__-fab[data-size=lg]{--__P__-fab-size: 68px;font-size:var(--__P__-text-base)}.__P__-fab{display:inline-flex;align-items:center;justify-content:center;gap:var(--__P__-space-2);color:var(--__P__-accent-text);background:var(--__P__-accent);box-shadow:var(--__P__-shadow-fab);font-weight:600;line-height:1;transform-origin:bottom right;animation:__P__-fab-in var(--__P__-dur-base) var(--__P__-ease) both;transition:transform var(--__P__-dur-base) var(--__P__-ease),opacity var(--__P__-dur-base) var(--__P__-ease),box-shadow var(--__P__-dur-base) var(--__P__-ease)}.__P__-fab:hover{transform:translateY(-2px)}.__P__-fab:active{transform:translateY(0)}.__P__-fab:focus-visible{outline:2px solid var(--__P__-on-accent);outline-offset:3px}.__P__-fab svg{width:24px;height:24px;flex-shrink:0}@keyframes __P__-fab-in{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:none}}.__P__-fab[data-leaving]{position:absolute;right:0;bottom:0;animation:__P__-fab-out var(--__P__-dur-quick) var(--__P__-ease) forwards;pointer-events:none}:host([data-position^="top-"]) .__P__-fab[data-leaving]{bottom:auto;top:0}:host([data-position$="-left"]) .__P__-fab[data-leaving]{right:auto;left:0}@keyframes __P__-fab-out{0%{opacity:1;transform:none}to{opacity:0;transform:scale(.85)}}.__P__-fab[data-variant=circle]{width:var(--__P__-fab-size);height:var(--__P__-fab-size);border-radius:999px}.__P__-fab[data-variant=circle] .__P__-fab-label{display:none}.__P__-fab[data-variant=pill]{height:var(--__P__-fab-size);padding:0 18px 0 16px;border-radius:999px}.__P__-fab[data-variant=bar]{height:var(--__P__-fab-size);padding:0 22px;border-radius:var(--__P__-radius)}.__P__-fab[data-variant=minimal]{height:var(--__P__-fab-size);padding:0 var(--__P__-space-4);border-radius:999px;background:transparent;color:var(--__P__-accent);box-shadow:none;border:1px solid currentColor}.__P__-fab[data-variant=minimal]:hover{background:color-mix(in srgb,var(--__P__-accent) 12%,transparent)}.__P__-callout{--__P__-callout-fab-h: var(--__P__-fab-size, 56px);--__P__-callout-gap: clamp(12px, calc(var(--__P__-callout-fab-h) * .25), 22px);--__P__-callout-nudge-direction: -1;position:absolute;display:inline-flex;align-items:center;gap:var(--__P__-space-2);padding:10px 14px;background:var(--__P__-fg);color:var(--__P__-bg);border-radius:999px;font-size:var(--__P__-text-sm);font-weight:600;line-height:1.2;box-shadow:0 10px 30px -8px #00000059;pointer-events:auto;animation:__P__-callout-in var(--__P__-dur-slow) var(--__P__-ease);z-index:1;max-width:240px;white-space:nowrap}.__P__-callout[data-position=left]{right:calc(100% + var(--__P__-callout-gap));bottom:calc(var(--__P__-callout-fab-h) / 2);transform:translateY(50%)}.__P__-callout[data-position=right]{left:calc(100% + var(--__P__-callout-gap));bottom:calc(var(--__P__-callout-fab-h) / 2);transform:translateY(50%);--__P__-callout-nudge-direction: 1}.__P__-callout[data-position=top]{bottom:calc(100% + var(--__P__-callout-gap));right:0;max-width:min(280px,calc(100vw - 32px))}.__P__-callout[data-position=bottom]{top:calc(100% + var(--__P__-callout-gap));right:0;max-width:min(280px,calc(100vw - 32px))}:host([data-position$="-left"]) .__P__-callout[data-position=top],:host([data-position$="-left"]) .__P__-callout[data-position=bottom]{right:auto;left:0}.__P__-callout[data-shape=bubble]{border-radius:var(--__P__-radius-md);white-space:normal;width:max-content;max-width:min(280px,calc(100vw - 32px))}.__P__-callout[data-shape=callout]{padding:12px 18px;font-size:14px;background:var(--__P__-accent);color:var(--__P__-accent-text)}.__P__-callout:after{content:"";position:absolute;width:12px;height:12px;background:inherit;border-radius:2px;transform:rotate(45deg)}.__P__-callout[data-position=left]:after{right:-5px;top:50%;margin-top:-6px}.__P__-callout[data-position=right]:after{left:-5px;top:50%;margin-top:-6px}.__P__-callout[data-position=top]:after{bottom:-5px;right:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}.__P__-callout[data-position=bottom]:after{top:-5px;right:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}:host([data-position$="-left"]) .__P__-callout[data-position=top]:after,:host([data-position$="-left"]) .__P__-callout[data-position=bottom]:after{right:auto;left:calc(var(--__P__-fab-size, 56px) / 2 - 6px)}.__P__-callout[data-animated]{animation:__P__-callout-in var(--__P__-dur-slow) var(--__P__-ease),__P__-callout-nudge 1.6s var(--__P__-ease-in-out) var(--__P__-dur-slow) infinite}@keyframes __P__-callout-in{0%{opacity:0}to{opacity:1}}@keyframes __P__-callout-nudge{0%,to{margin-left:0;margin-right:0}50%{margin-left:calc(6px * var(--__P__-callout-nudge-direction));margin-right:calc(-6px * var(--__P__-callout-nudge-direction))}}@media(prefers-reduced-motion:reduce){.__P__-callout[data-animated]{animation:__P__-callout-in 1ms var(--__P__-ease)}.__P__-icon-btn[data-recording=true],.__P__-typing span{animation:none}}.__P__-callout-close{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:inherit;opacity:.7;cursor:pointer}.__P__-callout-close:hover{opacity:1;background:#ffffff26}.__P__-callout-close svg{width:12px;height:12px}.__P__-panel{width:var(--__P__-panel-w);height:var(--__P__-panel-h);max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);background:var(--__P__-bg);color:var(--__P__-fg);border-radius:var(--__P__-radius-lg);box-shadow:var(--__P__-shadow-panel);display:flex;flex-direction:column;overflow:hidden;transform-origin:bottom right;animation:__P__-panel-in var(--__P__-dur-slow) var(--__P__-ease);border:1px solid var(--__P__-border)}:host([data-mode="open"]) .__P__-panel{width:var(--__P__-widget-w, var(--__P__-panel-w));height:var(--__P__-widget-h, var(--__P__-panel-h));min-width:var(--__P__-resize-min-w, auto);min-height:var(--__P__-resize-min-h, auto);max-width:var(--__P__-resize-max-w, calc(100vw - 32px) );max-height:var(--__P__-resize-max-h, calc(100dvh - 32px) )}@keyframes __P__-panel-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:none}}:host([data-mode="expanded"]) .__P__-panel{width:var(--__P__-expanded-w, 640px);height:var(--__P__-expanded-h, 820px);max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px)}:host([data-mode="fullscreen"]){z-index:var(--__P__-z-panel)!important}:host([data-mode="fullscreen"]) .__P__-anchor{inset:0;align-items:stretch;padding:0}:host([data-mode="fullscreen"]) .__P__-panel{width:100vw;height:100dvh;max-width:none;max-height:none;border-radius:0;border:0}:host([data-mode="fullscreen"]) .__P__-fab{display:none}:host([data-mode="inline"]) .__P__-anchor,:host([data-mode="standalone"]) .__P__-anchor{position:static;inset:auto;padding:0;align-items:stretch;width:100%;height:100%;min-height:0}:host([data-mode="inline"]) .__P__-panel,:host([data-mode="standalone"]) .__P__-panel{width:100%;height:100%;min-width:0;min-height:0;max-width:none;max-height:none;animation:none}:host([data-mode="inline"]) .__P__-fab,:host([data-mode="standalone"]) .__P__-fab{display:none}:host([data-mode="inline"]){min-height:320px}:host([data-mode="inline"]) .__P__-panel{border-radius:var(--__P__-radius)}:host([data-mode="standalone"]) .__P__-panel{border-radius:0;border:0;box-shadow:none}:host([data-mode="modal"]){position:fixed!important;inset:0!important;z-index:var(--__P__-z-panel)!important;display:block!important;width:100vw;height:100dvh;background:var(--__P__-modal-backdrop, var(--__P__-backdrop));animation:__P__-backdrop-in var(--__P__-dur-base) var(--__P__-ease) both;--__P__-panel-w: min(960px, 92vw);--__P__-panel-h: min(720px, 88dvh)}:host([data-mode="modal"]) .__P__-anchor{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:var(--__P__-space-6);pointer-events:none}:host([data-mode="modal"]) .__P__-panel{pointer-events:auto;width:var(--__P__-widget-w, var(--__P__-panel-w));height:var(--__P__-widget-h, var(--__P__-panel-h));max-width:calc(100vw - 48px);max-height:calc(100dvh - 48px);min-width:0;min-height:0;border-radius:var(--__P__-radius);box-shadow:var(--__P__-shadow-panel);animation:__P__-modal-in var(--__P__-dur-base) var(--__P__-ease);translate:var(--__P__-modal-dx, 0px) var(--__P__-modal-dy, 0px)}:host([data-mode="modal"]) .__P__-header,:host([data-mode="modal"]) .__P__-back-header,:host([data-mode="modal"]) .__P__-home-hero{cursor:grab;touch-action:none}:host([data-mode="modal"]) .__P__-panel[data-dragging]{cursor:grabbing;user-select:none}:host([data-mode="modal"]) .__P__-panel[data-dragging] *{cursor:grabbing}:host([data-mode="modal"]) .__P__-fab{display:none}@keyframes __P__-backdrop-in{0%{background:#0000}to{background:var(--__P__-modal-backdrop, var(--__P__-backdrop))}}@keyframes __P__-modal-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}:host([data-mode="drawer"]){--__P__-panel-w: min(440px, calc(100vw - 32px) );--__P__-panel-h: 100dvh}:host([data-mode="drawer"]) .__P__-anchor{position:fixed;--__P__-inset-x: var(--__P__-panel-inset, 12px);--__P__-inset-y: var(--__P__-panel-inset, 3dvh);top:var(--__P__-inset-y);bottom:auto;right:var(--__P__-inset-x);left:auto;width:min(var(--__P__-widget-w, var(--__P__-panel-w)),calc(100vw - var(--__P__-inset-x) * 2));height:min(var(--__P__-widget-h, var(--__P__-panel-h)),calc(100dvh - var(--__P__-inset-y) * 2));padding:0;display:block;pointer-events:auto}:host([data-mode="drawer"][data-position$="-left"]) .__P__-anchor{right:auto;left:var(--__P__-inset-x)}:host([data-mode="drawer"][data-position^="bottom-"]) .__P__-anchor{top:auto;bottom:var(--__P__-inset-y)}:host([data-mode="drawer"]) .__P__-panel{width:100%;height:100%;max-width:none;max-height:none;min-width:0;min-height:0;border-radius:var(--__P__-radius, 12px);border:1px solid var(--__P__-border);box-shadow:-8px 16px 32px -12px #00000038;animation:__P__-drawer-in var(--__P__-dur-base) var(--__P__-ease)}:host([data-mode="drawer"][data-position$="-left"]) .__P__-panel{box-shadow:8px 16px 32px -12px #00000038;animation:__P__-drawer-in-left var(--__P__-dur-base) var(--__P__-ease)}.__P__-fab[data-edge-tab]{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--__P__-space-2);position:fixed;top:50%;height:140px;width:auto;min-width:0;padding:10px 8px;writing-mode:vertical-rl;text-orientation:mixed;transform:translateY(-50%);transform-origin:center;animation:__P__-edge-tab-in var(--__P__-dur-base) var(--__P__-ease) both}.__P__-fab[data-edge-tab] svg{writing-mode:horizontal-tb}.__P__-fab[data-edge-tab]:hover{transform:translateY(-50%) scale(1.03)}.__P__-fab[data-edge-tab]:active{transform:translateY(-50%) scale(.97)}:host([data-position$="-right"]) .__P__-fab[data-edge-tab]{right:0;left:auto;border-radius:12px 0 0 12px;box-shadow:-6px 0 18px -8px #0000004d}:host([data-position$="-left"]) .__P__-fab[data-edge-tab]{left:0;right:auto;border-radius:0 12px 12px 0;box-shadow:6px 0 18px -8px #0000004d}.__P__-fab[data-edge-tab][data-leaving]{position:fixed;top:50%;bottom:auto;animation:__P__-edge-tab-out var(--__P__-dur-quick) var(--__P__-ease) forwards}@keyframes __P__-edge-tab-in{0%{opacity:0;transform:translateY(-50%) scale(.9)}to{opacity:1;transform:translateY(-50%) scale(1)}}@keyframes __P__-edge-tab-out{0%{opacity:1;transform:translateY(-50%) scale(1)}to{opacity:0;transform:translateY(-50%) scale(.85)}}@keyframes __P__-drawer-in{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes __P__-drawer-in-left{0%{transform:translate(-100%)}to{transform:translate(0)}}@media(prefers-reduced-motion:reduce){:host([data-mode="drawer"]) .__P__-panel,.__P__-fab[data-edge-tab]{animation:none}}.__P__-header{display:flex;align-items:center;gap:var(--__P__-space-2);padding:10px 12px;border-bottom:1px solid var(--__P__-border);background:var(--__P__-bg)}.__P__-header h1{font-size:14px;font-weight:600;flex:1;letter-spacing:-.01em}.__P__-header-actions{margin-left:auto;display:flex;align-items:center;gap:var(--__P__-space-1);flex-shrink:0}.__P__-agent{flex:1;display:inline-flex;align-items:center;gap:10px;min-width:0}.__P__-agent-avatar{position:relative;width:32px;height:32px;border-radius:999px;background:var(--__P__-bg-elevated);color:var(--__P__-fg-muted);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--__P__-text-xs);overflow:hidden;flex-shrink:0}.__P__-agent-avatar img{width:100%;height:100%;object-fit:cover}.__P__-agent-avatar:after{content:"";position:absolute;right:-1px;bottom:-1px;width:10px;height:10px;border-radius:999px;border:2px solid var(--__P__-bg);background:var(--__P__-neutral)}.__P__-agent-avatar[data-status=online]:after{background:var(--__P__-success)}.__P__-agent-avatar[data-status=away]:after{background:var(--__P__-warning)}.__P__-agent-avatar[data-status=offline]:after{background:var(--__P__-neutral)}.__P__-agent-meta{display:flex;flex-direction:column;line-height:1.15;min-width:0}.__P__-agent-meta strong{font-size:14px;font-weight:600;letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-agent-meta span{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-suggestions{display:flex;flex-wrap:nowrap;gap:var(--__P__-space-2);padding:6px 14px 10px;overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scroll-snap-type:x proximity;scrollbar-width:none;-ms-overflow-style:none;min-width:0}.__P__-suggestions::-webkit-scrollbar{display:none}.__P__-suggestions:before,.__P__-suggestions:after{content:"";flex:1 1 0;min-width:0}.__P__-suggestion{flex:0 0 auto;scroll-snap-align:center;padding:7px 14px;border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);color:var(--__P__-fg);font-size:var(--__P__-text-sm);font-weight:500;white-space:nowrap;transition:background var(--__P__-dur-quick) var(--__P__-ease),border-color var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease)}.__P__-suggestion:hover{border-color:var(--__P__-accent);color:var(--__P__-accent);transform:translateY(-1px)}.__P__-suggestion:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px;border-color:var(--__P__-accent)}.__P__-suggestion:active{transform:translateY(0)}.__P__-icon-btn{width:32px;height:32px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted);transition:background var(--__P__-dur-quick) var(--__P__-ease),color var(--__P__-dur-quick) var(--__P__-ease)}.__P__-icon-btn:hover{background:var(--__P__-bg-elevated);color:var(--__P__-fg)}.__P__-icon-btn:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-icon-btn:active{background:var(--__P__-border)}.__P__-icon-btn:disabled{opacity:.45;cursor:not-allowed}.__P__-icon-btn:before{content:"";position:absolute;inset:-6px}.__P__-icon-btn{position:relative}.__P__-icon-btn svg{width:18px;height:18px}.__P__-icon-btn[data-recording=true]{color:var(--__P__-accent);background:color-mix(in srgb,var(--__P__-accent) 12%,transparent);animation:__P__-pulse 1.2s var(--__P__-ease) infinite}@keyframes __P__-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--__P__-accent) 40%,transparent)}50%{box-shadow:0 0 0 6px color-mix(in srgb,var(--__P__-accent) 0%,transparent)}}.__P__-list-wrap{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}.__P__-jump{position:absolute;right:14px;bottom:14px;z-index:2;display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:999px;border:1px solid var(--__P__-border);background:var(--__P__-bg-elevated);color:var(--__P__-fg);box-shadow:var(--__P__-shadow-panel);cursor:pointer;opacity:.85;transition:opacity var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease);animation:__P__-bubble-in var(--__P__-dur-base) var(--__P__-ease)}.__P__-jump:hover{opacity:1}.__P__-jump:active{transform:translateY(1px)}.__P__-jump svg{width:18px;height:18px}.__P__-list{flex:1;min-height:0;overflow-y:auto;padding:var(--__P__-space-4);padding-bottom:var(--__P__-space-8);display:flex;flex-direction:column;gap:14px;scrollbar-width:thin;scrollbar-color:var(--__P__-border-strong) transparent;scrollbar-gutter:stable}.__P__-list::-webkit-scrollbar{width:8px}.__P__-list::-webkit-scrollbar-thumb{background:var(--__P__-border-strong);border-radius:8px}.__P__-date-divider{position:sticky;top:var(--__P__-space-2);z-index:2;display:flex;justify-content:center;margin:var(--__P__-space-1) 0;pointer-events:none}.__P__-date-pill{padding:3px 10px;border-radius:999px;font-size:11px;font-weight:600;color:var(--__P__-fg-muted);background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);box-shadow:var(--__P__-shadow-card);opacity:0;pointer-events:none;transition:opacity var(--__P__-dur-base) var(--__P__-ease)}.__P__-list[data-scrolling=true] .__P__-date-pill{opacity:1;pointer-events:auto}@media(prefers-reduced-motion:reduce){.__P__-date-pill{transition:none}}.__P__-bubble-row{display:flex}.__P__-bubble-row[data-role=user]{justify-content:flex-end}.__P__-bubble-row[data-role=assistant]{justify-content:flex-start}.__P__-bubble{max-width:100%;padding:var(--__P__-space-3) var(--__P__-space-4);border-radius:var(--__P__-radius);line-height:1.6;font-size:14px;word-wrap:break-word;overflow-wrap:anywhere;box-shadow:0 1px 2px #0000000a,0 1px 8px -4px #0000000f;animation:__P__-bubble-in var(--__P__-dur-base) var(--__P__-ease)}.__P__-bubble ::selection{background:color-mix(in srgb,var(--__P__-accent) 30%,transparent)}.__P__-bubble-row[data-role=user] .__P__-bubble ::selection{background:#fff6;color:var(--__P__-bubble-user-text)}@keyframes __P__-bubble-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}.__P__-bubble-row[data-role=user] .__P__-bubble{background:var(--__P__-bubble-user);color:var(--__P__-bubble-user-text);border-bottom-right-radius:5px}.__P__-bubble-row[data-role=assistant] .__P__-bubble{background:var(--__P__-bubble-assistant);color:var(--__P__-bubble-assistant-text);border-bottom-left-radius:5px}.__P__-bubble-col{display:flex;flex-direction:column;max-width:85%;min-width:0}.__P__-bubble-row[data-role=user] .__P__-bubble-col{align-items:flex-end}.__P__-bubble-row[data-role=assistant] .__P__-bubble-col{align-items:flex-start}.__P__-bubble-time{margin-top:3px;padding:0 4px;font-size:11px;line-height:1;color:var(--__P__-fg-muted);user-select:none}.__P__-md>*:first-child{margin-top:0}.__P__-md>*:last-child{margin-bottom:0}.__P__-md p{margin:10px 0}.__P__-md h1,.__P__-md h2,.__P__-md h3,.__P__-md h4,.__P__-md h5,.__P__-md h6{margin:18px 0 8px;line-height:1.3;letter-spacing:-.01em;font-weight:700}.__P__-md h1{font-size:1.4em}.__P__-md h2{font-size:1.22em}.__P__-md h3{font-size:1.08em}.__P__-md h4,.__P__-md h5,.__P__-md h6{font-size:1em}.__P__-md>h1:first-child,.__P__-md>h2:first-child,.__P__-md>h3:first-child,.__P__-md>h4:first-child,.__P__-md>h5:first-child,.__P__-md>h6:first-child{margin-top:0}.__P__-md ul,.__P__-md ol{padding-left:1.5em;margin:10px 0}.__P__-md ul{list-style:disc}.__P__-md ol{list-style:decimal}.__P__-md li{margin:6px 0;padding-left:2px}.__P__-md li::marker{color:var(--__P__-fg-muted)}.__P__-md li>p{margin:6px 0}.__P__-md li>ul,.__P__-md li>ol{margin:6px 0}.__P__-md strong,.__P__-md b{font-weight:650;letter-spacing:-.005em}.__P__-md em,.__P__-md i{font-style:italic}.__P__-md code{font-family:var(--__P__-font-mono);font-size:.86em;padding:1px 6px;border-radius:5px;background:color-mix(in srgb,var(--__P__-accent) 10%,transparent);color:var(--__P__-fg);border:1px solid color-mix(in srgb,var(--__P__-accent) 16%,transparent)}.__P__-md pre{font-family:var(--__P__-font-mono);font-size:12.5px;padding:12px 14px;border-radius:var(--__P__-radius-sm);background:#7f7f7f1f;overflow-x:auto;margin:var(--__P__-space-3) 0;line-height:1.5}.__P__-md pre code{padding:0;background:none}.__P__-md a{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px}.__P__-md a:hover{text-decoration-thickness:2px}.__P__-md blockquote{margin:14px 0;padding:6px 14px;border-left:3px solid color-mix(in srgb,var(--__P__-accent) 50%,transparent);background:color-mix(in srgb,var(--__P__-accent) 5%,transparent);border-radius:0 var(--__P__-radius-sm) var(--__P__-radius-sm) 0;color:var(--__P__-fg-muted)}.__P__-md blockquote>:first-child{margin-top:0}.__P__-md blockquote>:last-child{margin-bottom:0}.__P__-md hr{border:0;height:1px;background:color-mix(in srgb,currentColor 18%,transparent);margin:var(--__P__-space-4) 0}.__P__-md table{border-collapse:collapse;margin:var(--__P__-space-3) 0;font-size:.95em;display:block;overflow-x:auto;max-width:100%;font-variant-numeric:tabular-nums}.__P__-md th,.__P__-md td{padding:6px 10px;border-bottom:1px solid color-mix(in srgb,currentColor 12%,transparent);text-align:left}.__P__-md th{font-weight:700;background:color-mix(in srgb,currentColor 6%,transparent)}.__P__-md h1+ul,.__P__-md h1+ol,.__P__-md h2+ul,.__P__-md h2+ol,.__P__-md h3+ul,.__P__-md h3+ol,.__P__-md h4+ul,.__P__-md h4+ol{margin-top:var(--__P__-space-1)}.__P__-loading{display:inline-flex;align-items:center;gap:var(--__P__-space-2);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm)}.__P__-loading-spinner{width:14px;height:14px;border-radius:999px;border:2px solid currentColor;border-top-color:transparent;animation:__P__-spin .8s linear infinite}@keyframes __P__-spin{to{transform:rotate(1turn)}}.__P__-typing{display:inline-flex;gap:var(--__P__-space-1);padding:var(--__P__-space-1) 0}.__P__-typing span{width:5px;height:5px;border-radius:999px;background:currentColor;opacity:.4;animation:__P__-blink 1.2s var(--__P__-ease) infinite}.__P__-typing span:nth-child(2){animation-delay:.2s}.__P__-typing span:nth-child(3){animation-delay:.4s}@keyframes __P__-blink{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-2px)}}.__P__-reasoning{margin:var(--__P__-space-1) 0 var(--__P__-space-2);padding-left:var(--__P__-space-3);border-left:2px solid var(--__P__-border-strong)}.__P__-reasoning-summary{display:inline-flex;align-items:center;gap:var(--__P__-space-1);cursor:pointer;list-style:none;user-select:none;color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600}.__P__-reasoning-summary::-webkit-details-marker{display:none}.__P__-reasoning-summary:before{content:"";width:5px;height:5px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);opacity:.7;transition:transform var(--__P__-dur-quick) var(--__P__-ease)}.__P__-reasoning[open] .__P__-reasoning-summary:before{transform:rotate(45deg)}.__P__-reasoning[data-active=true] .__P__-reasoning-label{animation:__P__-reasoning-pulse 1.4s var(--__P__-ease) infinite}@keyframes __P__-reasoning-pulse{0%,to{opacity:.5}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.__P__-reasoning[data-active=true] .__P__-reasoning-label{animation:none}}.__P__-reasoning-body{margin-top:var(--__P__-space-1);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm)}.__P__-reasoning-body>:first-child{margin-top:0}.__P__-reasoning-body>:last-child{margin-bottom:0}.__P__-tool-chip{display:inline-flex;align-items:center;gap:6px;padding:var(--__P__-space-1) var(--__P__-space-2);margin-top:6px;border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs)}.__P__-composer{border-top:1px solid var(--__P__-border);padding:10px 12px;background:var(--__P__-bg);display:flex;flex-direction:column;gap:var(--__P__-space-2)}.__P__-composer-row{display:flex;align-items:flex-end;gap:6px}.__P__-textarea{flex:1;height:40px;max-height:160px;padding:10px 12px;border-radius:var(--__P__-radius);background:var(--__P__-bg-elevated);border:1px solid transparent;font-size:14px;line-height:1.4;transition:height var(--__P__-dur-quick) var(--__P__-ease),border-color var(--__P__-dur-quick) var(--__P__-ease),box-shadow var(--__P__-dur-quick) var(--__P__-ease)}.__P__-textarea:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:1px;border-color:var(--__P__-focus)}@media(pointer:coarse){.__P__-textarea,.__P__-home-search-input{font-size:16px}.__P__-textarea{height:44px}}.__P__-send{width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;transition:opacity var(--__P__-dur-quick) var(--__P__-ease),transform var(--__P__-dur-quick) var(--__P__-ease),background var(--__P__-dur-quick) var(--__P__-ease)}.__P__-send[data-shape=circle]{border-radius:999px}.__P__-send[data-shape=square]{border-radius:var(--__P__-radius-sm)}.__P__-send[data-shape=pill]{width:auto;padding:0 18px;border-radius:999px}.__P__-send[data-variant=filled]{background:var(--__P__-accent);color:var(--__P__-accent-text)}.__P__-send[data-variant=outline]{background:transparent;color:var(--__P__-accent);border-color:var(--__P__-accent)}.__P__-send[data-variant=outline]:not(:disabled):hover{background:color-mix(in srgb,var(--__P__-accent) 10%,transparent)}.__P__-send[data-variant=ghost]{background:transparent;color:var(--__P__-accent)}.__P__-send[data-variant=ghost]:not(:disabled):hover{background:color-mix(in srgb,var(--__P__-accent) 8%,transparent)}.__P__-send:disabled{opacity:.4;cursor:not-allowed}.__P__-send:not(:disabled):hover{transform:translateY(-1px)}.__P__-send:not(:disabled):active{transform:translateY(0)}.__P__-send:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-send svg{width:18px;height:18px}.__P__-composer-actions{display:flex;gap:var(--__P__-space-1);flex-wrap:wrap}.__P__-attachments{display:flex;flex-wrap:wrap;gap:6px}.__P__-attachment-chip{display:inline-flex;align-items:center;gap:6px;padding:var(--__P__-space-1) var(--__P__-space-2) var(--__P__-space-1) var(--__P__-space-1);border-radius:999px;background:var(--__P__-bg-elevated);border:1px solid var(--__P__-border);font-size:var(--__P__-text-xs);max-width:200px}.__P__-attachment-thumb{width:24px;height:24px;border-radius:999px;object-fit:cover;background:var(--__P__-border)}.__P__-attachment-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__P__-attachment-remove{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted)}.__P__-attachment-remove:hover{background:var(--__P__-border);color:var(--__P__-fg)}.__P__-dropzone{position:absolute;inset:8px;border:2px dashed var(--__P__-accent);border-radius:var(--__P__-radius);background:color-mix(in srgb,var(--__P__-accent) 8%,transparent);display:flex;align-items:center;justify-content:center;font-weight:600;color:var(--__P__-accent);pointer-events:none;z-index:10;animation:__P__-fade-in var(--__P__-dur-quick) var(--__P__-ease)}@keyframes __P__-fade-in{0%{opacity:0}to{opacity:1}}.__P__-error{margin-top:var(--__P__-space-1);padding:8px 10px;border-radius:var(--__P__-radius-sm);background:var(--__P__-danger-bg);color:var(--__P__-danger-text);font-size:var(--__P__-text-sm);display:flex;align-items:center;gap:var(--__P__-space-2)}.__P__-error button{color:inherit;text-decoration:underline;font-size:var(--__P__-text-sm)}.__P__-history{flex:1;overflow-y:auto;padding:var(--__P__-space-2) var(--__P__-space-1) var(--__P__-space-3)}.__P__-history-footer{flex:none;padding:var(--__P__-space-2) var(--__P__-space-3) var(--__P__-space-3);border-top:1px solid var(--__P__-border);background:var(--__P__-surface)}.__P__-history-new{width:100%;display:flex;align-items:center;justify-content:center;gap:var(--__P__-space-2);padding:var(--__P__-space-2) var(--__P__-space-3);border:none;border-radius:var(--__P__-radius-md);background:var(--__P__-accent);color:var(--__P__-on-accent);cursor:pointer;font-size:var(--__P__-text-sm);font-weight:600;transition:filter var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-history-new svg{width:16px;height:16px}.__P__-history-new:hover{filter:brightness(1.08)}.__P__-history-new:active{transform:translateY(1px)}.__P__-history-new:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-history-empty{flex:1;display:flex;align-items:center;justify-content:center;padding:40px 16px;color:var(--__P__-fg-muted);font-size:14px;text-align:center}.__P__-history-group{display:flex;flex-direction:column;padding:0 var(--__P__-space-2)}.__P__-history-heading{font-size:var(--__P__-text-xs);font-weight:600;color:var(--__P__-fg-muted);padding:12px 8px 6px;text-transform:uppercase;letter-spacing:.04em}.__P__-history-item{all:unset;display:flex;flex-direction:column;gap:3px;padding:10px 12px;border-radius:var(--__P__-radius-md);cursor:pointer;transition:background var(--__P__-dur-base) var(--__P__-ease)}.__P__-history-item:hover{background:var(--__P__-bg-elevated)}.__P__-history-item:focus-visible{background:var(--__P__-bg-elevated);outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-history-title{font-size:14px;font-weight:500;color:var(--__P__-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-history-preview{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-history-item[data-closed=true] .__P__-history-title:after{content:"\\2022";margin-left:var(--__P__-space-2);opacity:.5}.__P__-list-loading{margin:auto;padding:var(--__P__-space-6) var(--__P__-space-4);color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);text-align:center}.__P__-readonly-banner{display:flex;flex-direction:column;align-items:center;gap:10px;padding:14px 12px;margin:0 var(--__P__-space-3) var(--__P__-space-3);border-radius:var(--__P__-radius-md);background:var(--__P__-bg-elevated);color:var(--__P__-fg-muted);text-align:center;font-size:var(--__P__-text-sm)}.__P__-readonly-label{line-height:1.4}.__P__-readonly-cta{appearance:none;border:0;cursor:pointer;padding:var(--__P__-space-2) var(--__P__-space-4);border-radius:999px;background:var(--__P__-accent);color:var(--__P__-accent-text, #fff);font:inherit;font-weight:600;font-size:var(--__P__-text-sm);transition:filter var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-readonly-cta:hover,.__P__-readonly-cta:focus-visible{filter:brightness(1.1)}.__P__-readonly-cta:focus-visible{outline:2px solid var(--__P__-accent);outline-offset:2px}.__P__-composer-footer{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:10px 16px;margin:0 var(--__P__-space-3);border-top:1px solid var(--__P__-border);text-align:center;font-size:11px;line-height:1.4;color:var(--__P__-fg-muted)}.__P__-disclaimer{max-width:320px;margin:0 auto;opacity:.9;letter-spacing:.01em}.__P__-poweredby{display:inline-flex;align-items:center;justify-content:center;gap:6px;color:inherit;text-decoration:none;opacity:.7;transition:opacity var(--__P__-dur-base) var(--__P__-ease);font-size:11px;letter-spacing:.02em}.__P__-poweredby:hover{opacity:1}.__P__-poweredby-logo{height:12px;width:auto;display:inline-block;vertical-align:middle}.__P__-poweredby-bar{flex:none;display:flex;align-items:center;justify-content:center;padding:6px 16px;border-top:1px solid var(--__P__-border);background:var(--__P__-bg-elevated)}.__P__-menu-wrap{position:relative;display:inline-flex}.__P__-menu{position:absolute;top:100%;right:0;margin-top:6px;min-width:200px;padding:6px;background:var(--__P__-bg);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);box-shadow:var(--__P__-shadow-panel);z-index:10;display:flex;flex-direction:column;gap:2px;animation:__P__-menu-in var(--__P__-dur-base) var(--__P__-ease)}@media(prefers-reduced-motion:reduce){.__P__-menu{animation:none}}@keyframes __P__-menu-in{0%{opacity:0;transform:translateY(-4px) scale(.98);transform-origin:top right}to{opacity:1;transform:none}}.__P__-menu-item{all:unset;display:flex;align-items:center;gap:10px;padding:8px 10px;font-size:var(--__P__-text-sm);color:var(--__P__-fg);border-radius:var(--__P__-radius-sm);cursor:pointer;user-select:none}.__P__-menu-item:hover{background:var(--__P__-bg-elevated)}.__P__-menu-item:focus-visible{background:var(--__P__-bg-elevated);outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-menu-item[disabled]{opacity:.45;cursor:not-allowed}.__P__-menu-icon{display:inline-flex;width:16px;height:16px;color:var(--__P__-fg-muted)}.__P__-menu-icon svg{width:16px;height:16px}.__P__-menu-label{flex:1}.__P__-menu-check{display:inline-flex;color:var(--__P__-accent)}.__P__-menu-check svg{width:14px;height:14px}.__P__-resize-grip{position:absolute;width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:var(--__P__-fg-muted);opacity:.45;transition:opacity var(--__P__-dur-base) var(--__P__-ease);z-index:2;touch-action:none;user-select:none}.__P__-resize-grip:hover,.__P__-resize-grip:focus-visible{opacity:1}.__P__-resize-grip svg{width:10px;height:10px}.__P__-resize-grip--bottom-left{bottom:2px;left:2px;cursor:nesw-resize;transform:scaleX(-1)}.__P__-resize-grip--bottom-right{bottom:2px;right:2px;cursor:nwse-resize}.__P__-resize-grip--top-left{top:2px;left:2px;cursor:nwse-resize;transform:rotate(180deg)}.__P__-resize-grip--top-right{top:2px;right:2px;cursor:nesw-resize;transform:scaleY(-1)}:host(:not([data-mode="open"])) .__P__-resize-grip{display:none}.__P__-messenger{display:flex;flex-direction:column;overflow:hidden}.__P__-messenger-body{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}.__P__-module{display:flex;flex-direction:column;height:100%;min-height:0}.__P__-module-scroll{flex:1;min-height:0;overflow-y:auto;padding:var(--__P__-space-3);display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-home{background:radial-gradient(125% 65% at 88% 0%,color-mix(in srgb,#fff 16%,transparent),transparent 55%),linear-gradient(180deg,var(--__P__-accent) 0%,var(--__P__-accent) 22%,color-mix(in srgb,var(--__P__-accent) 28%,var(--__P__-surface)) 44%,var(--__P__-surface) 70%);border-radius:var(--__P__-radius-lg) var(--__P__-radius-lg) 0 0}.__P__-home-scroll{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;background:transparent}.__P__-home-cards{display:flex;flex-direction:column;gap:var(--__P__-space-3);padding:4px 14px 16px}.__P__-module-pad{padding:var(--__P__-space-3) var(--__P__-space-3) 0}.__P__-module-empty{display:flex;flex-direction:column;align-items:center;gap:var(--__P__-space-3);padding:var(--__P__-space-8) var(--__P__-space-4);text-align:center;color:var(--__P__-fg-muted);font-size:var(--__P__-text-base)}.__P__-module-retry{padding:var(--__P__-space-2) var(--__P__-space-4);border:1px solid var(--__P__-border-strong);border-radius:var(--__P__-radius-sm);color:var(--__P__-fg);font-weight:600;cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out),border-color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-module-retry:hover{background:var(--__P__-hover);border-color:var(--__P__-accent)}.__P__-module-retry:active{background:var(--__P__-border)}.__P__-module-retry:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-help-list{flex:1;min-height:0;overflow-y:auto;padding-bottom:var(--__P__-space-3)}.__P__-help-group{display:flex;flex-direction:column}.__P__-help-section-title{position:sticky;top:0;z-index:1;margin:0;padding:var(--__P__-space-3) var(--__P__-space-5) var(--__P__-space-2);font-size:var(--__P__-text-xs);font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--__P__-fg-muted);background:var(--__P__-bg)}.__P__-help-card{margin:0 var(--__P__-space-3) var(--__P__-space-3);background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);overflow:hidden}.__P__-help-card .__P__-list-row{border-bottom:0;border-radius:0}.__P__-help-card .__P__-list-row+.__P__-list-row{border-top:1px solid var(--__P__-border)}.__P__-help-card .__P__-list-row:hover{background:var(--__P__-hover)}.__P__-module-cta{padding:var(--__P__-space-3);border-top:1px solid var(--__P__-border)}.__P__-tabbar{display:flex;border-top:1px solid var(--__P__-border);background:var(--__P__-bg-elevated);flex-shrink:0}.__P__-tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--__P__-space-1);min-height:48px;padding:var(--__P__-space-2) var(--__P__-space-1);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600;transition:color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-tab:hover{color:var(--__P__-fg)}.__P__-tab[aria-selected=true]{color:var(--__P__-accent)}.__P__-tab:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-tab:active{background:var(--__P__-hover)}.__P__-tab-icon{position:relative;display:inline-flex}.__P__-tab-icon svg{width:22px;height:22px}.__P__-tab-badge{position:absolute;top:-4px;left:calc(50% + 6px);min-width:16px;height:16px;padding:0 4px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:var(--__P__-accent);color:var(--__P__-on-accent);font-size:10px;font-weight:600;line-height:1}.__P__-home-hero{flex-shrink:0;padding:var(--__P__-space-5) var(--__P__-space-5) var(--__P__-space-3);color:var(--__P__-on-accent);--__P__-focus: var(--__P__-on-accent)}.__P__-home-hero-top{display:flex;align-items:center;justify-content:space-between;gap:var(--__P__-space-3);min-height:32px}.__P__-home-brand{font-size:14px;font-weight:600;letter-spacing:.01em;color:color-mix(in srgb,#fff 82%,transparent);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.__P__-home-brand-spacer{flex:1}.__P__-home-hero-actions{display:flex;align-items:center;gap:var(--__P__-space-2);flex-shrink:0}.__P__-home-hero-actions .__P__-icon-btn{color:#fff}.__P__-home-greeting{margin:28px 0 0;font-family:var(--__P__-font-display);font-size:var(--__P__-text-2xl);font-weight:800;line-height:1.18;letter-spacing:-.01em;overflow-wrap:anywhere}.__P__-home-lead{margin:2px 0 0;font-family:var(--__P__-font-display);font-size:var(--__P__-text-2xl);font-weight:800;line-height:1.18;letter-spacing:-.01em;color:color-mix(in srgb,var(--__P__-on-accent) 88%,transparent);overflow-wrap:anywhere}.__P__-home-avatars{display:flex}.__P__-home-avatar{width:30px;height:30px;border-radius:999px;overflow:hidden;margin-left:-10px;border:2px solid color-mix(in srgb,#fff 92%,transparent);box-shadow:0 1px 3px #0000002e;background:var(--__P__-surface);display:inline-flex;align-items:center;justify-content:center;font-size:var(--__P__-text-xs);font-weight:700;color:var(--__P__-fg)}.__P__-home-avatar:first-child{margin-left:0}.__P__-home-avatar img{width:100%;height:100%;object-fit:cover}.__P__-home-content{background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);box-shadow:var(--__P__-shadow-card);overflow:hidden}.__P__-home-content-title{padding:var(--__P__-space-4) var(--__P__-space-4) var(--__P__-space-3);font-size:var(--__P__-text-sm);font-weight:700}.__P__-home-content-list{display:flex;flex-direction:column;padding:0 var(--__P__-space-2) var(--__P__-space-2)}.__P__-home-content-list .__P__-list-row+.__P__-list-row{border-top:1px solid var(--__P__-border)}.__P__-home-card{display:block;width:100%;text-align:left;background:var(--__P__-surface);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);padding:var(--__P__-space-4);box-shadow:var(--__P__-shadow-card)}.__P__-home-card[data-interactive=true]{cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-home-card[data-interactive=true]:hover{background:var(--__P__-bg-elevated)}.__P__-home-card[data-interactive=true]:active{transform:translateY(1px)}.__P__-home-card[data-interactive=true]:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-home-recent-row{display:flex;align-items:center;gap:var(--__P__-space-3)}.__P__-home-recent-avatar{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;flex-shrink:0;border-radius:999px;background:color-mix(in oklch,var(--__P__-accent) 14%,transparent);color:var(--__P__-accent)}.__P__-home-recent-avatar svg{width:20px;height:20px}.__P__-home-recent-body{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}.__P__-home-recent-title{font-weight:600;font-size:14px}.__P__-home-recent-preview{color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.__P__-home-recent-at{color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);flex-shrink:0}.__P__-home-recent-dot{width:8px;height:8px;border-radius:999px;background:var(--__P__-accent);flex-shrink:0}.__P__-home-recent-row[data-unread=true] .__P__-home-recent-title{font-weight:700}.__P__-home-status{display:flex;align-items:center;gap:var(--__P__-space-3)}.__P__-home-status-icon svg{width:22px;height:22px;color:var(--__P__-success)}.__P__-home-status[data-level=degraded] .__P__-home-status-icon svg{color:var(--__P__-warning)}.__P__-home-status[data-level=down] .__P__-home-status-icon svg{color:var(--__P__-danger)}.__P__-home-status-text{font-weight:600;font-size:14px}.__P__-home-search{display:flex;align-items:center;gap:var(--__P__-space-2);width:100%;padding:var(--__P__-space-3) var(--__P__-space-4);border-radius:var(--__P__-radius);border:1px solid var(--__P__-border);background:var(--__P__-surface);text-align:left}.__P__-home-search[data-input=true]{background:var(--__P__-bg-elevated)}.__P__-home-search:hover{border-color:var(--__P__-border-strong)}.__P__-home-search:focus-visible,.__P__-home-search:focus-within{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-home-search-text{flex:1;color:var(--__P__-fg-muted);font-size:14px}.__P__-home-search-input{flex:1;border:0;background:transparent;font-size:14px;color:var(--__P__-fg);outline:none}.__P__-home-search-icon svg{width:18px;height:18px;color:var(--__P__-accent)}.__P__-list-row{display:flex;align-items:center;gap:var(--__P__-space-3);width:100%;min-height:44px;text-align:left;padding:var(--__P__-space-3) var(--__P__-space-2);border-radius:var(--__P__-radius-sm)}.__P__-list-row:hover{background:var(--__P__-bg-elevated)}.__P__-list-row:active{background:var(--__P__-border)}.__P__-list-row:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:-2px}.__P__-list-row-body{display:flex;flex-direction:column;min-width:0;flex:1}.__P__-list-row-title{font-weight:600;font-size:var(--__P__-text-md);line-height:1.35}.__P__-list-row-sub{color:var(--__P__-fg-muted);font-size:var(--__P__-text-sm);margin-top:var(--__P__-space-1);line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.__P__-list-row-chevron svg{width:18px;height:18px;color:var(--__P__-accent);flex-shrink:0}.__P__-back-header{display:flex;align-items:center;gap:var(--__P__-space-2);padding:10px 12px;border-bottom:1px solid var(--__P__-border);flex-shrink:0}.__P__-back-title{flex:1;text-align:center;font-size:var(--__P__-text-md);font-weight:700;margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.__P__-back-spacer{width:32px;height:1px}.__P__-content{display:flex;flex-direction:column;gap:14px;width:100%;max-width:68ch;margin:0 auto}.__P__-content-hero{width:100%;border-radius:var(--__P__-radius)}.__P__-content-subtitle{color:var(--__P__-fg-muted);margin:0}.__P__-content-frame{flex:1;min-height:0;width:100%;border:0;background:#fff}.__P__-news-list{display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-news-card{display:block;width:100%;text-align:left;border:1px solid var(--__P__-border);border-radius:var(--__P__-radius);overflow:hidden;background:var(--__P__-surface)}.__P__-news-card{transition:background var(--__P__-dur-quick) var(--__P__-ease-out),transform var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-news-card:hover{background:var(--__P__-bg-elevated)}.__P__-news-card:active{transform:translateY(1px)}.__P__-news-card:focus-visible{outline:2px solid var(--__P__-focus);outline-offset:2px}.__P__-news-hero{width:100%;display:block}.__P__-news-body{display:flex;flex-direction:column;gap:6px;padding:14px 16px}.__P__-news-tags{display:flex;gap:6px;flex-wrap:wrap}.__P__-news-tag{font-size:var(--__P__-text-xs);font-weight:600;color:var(--__P__-accent);background:color-mix(in srgb,var(--__P__-accent) 12%,transparent);padding:2px 8px;border-radius:999px}.__P__-news-title{font-weight:700;font-size:var(--__P__-text-md)}.__P__-news-summary{color:var(--__P__-fg-muted);font-size:14px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.__P__-modules-empty{display:flex;align-items:center;justify-content:center;position:relative}.__P__-modules-empty-close{position:absolute;top:12px;right:12px}.__P__-modules-empty-text{color:var(--__P__-fg-muted);font-size:var(--__P__-text-base)}.__P__-form{display:flex;flex-direction:column;gap:var(--__P__-space-3)}.__P__-field{display:flex;flex-direction:column;gap:4px}.__P__-field-label{font-size:var(--__P__-text-sm);font-weight:600;color:var(--__P__-fg)}.__P__-field-req{color:var(--__P__-danger)}.__P__-field-input{width:100%;box-sizing:border-box;padding:var(--__P__-space-2) var(--__P__-space-3);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);background:var(--__P__-bg);color:var(--__P__-fg);font:inherit;font-size:var(--__P__-text-sm);resize:vertical;transition:border-color var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-field-input:focus-visible{outline:none;border-color:var(--__P__-accent)}.__P__-field[data-invalid=true] .__P__-field-input{border-color:var(--__P__-danger)}.__P__-field-hint{font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted)}.__P__-field-error{font-size:var(--__P__-text-xs);color:var(--__P__-danger)}.__P__-field-choices{display:flex;flex-direction:column;gap:6px}.__P__-choice{display:flex;align-items:flex-start;gap:8px;font-size:var(--__P__-text-sm);color:var(--__P__-fg);cursor:pointer}.__P__-choice input{margin-top:2px;accent-color:var(--__P__-accent)}.__P__-form-actions{display:flex;justify-content:flex-end;gap:var(--__P__-space-2);margin-top:2px}.__P__-form-submit,.__P__-tool-approve{padding:var(--__P__-space-2) var(--__P__-space-4);border:none;border-radius:var(--__P__-radius-md);background:var(--__P__-accent);color:var(--__P__-accent-text, #fff);font:inherit;font-weight:600;font-size:var(--__P__-text-sm);cursor:pointer;transition:filter var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-form-submit:hover:not(:disabled),.__P__-tool-approve:hover:not(:disabled){filter:brightness(1.06)}.__P__-form-submit:disabled{opacity:.6;cursor:default}.__P__-form-skip,.__P__-tool-reject{padding:var(--__P__-space-2) var(--__P__-space-4);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);background:transparent;color:var(--__P__-fg-muted);font:inherit;font-size:var(--__P__-text-sm);cursor:pointer;transition:background var(--__P__-dur-quick) var(--__P__-ease-out)}.__P__-form-skip:hover:not(:disabled),.__P__-tool-reject:hover:not(:disabled){background:var(--__P__-bg-elevated)}.__P__-intake{display:flex;flex-direction:column;gap:var(--__P__-space-2);padding:var(--__P__-space-3) var(--__P__-space-4) var(--__P__-space-4);border-top:1px solid var(--__P__-border);overflow-y:auto}.__P__-intake-title{margin:0;font-size:var(--__P__-text-base);font-weight:700;color:var(--__P__-fg)}.__P__-intake-desc{margin:0 0 var(--__P__-space-1);font-size:var(--__P__-text-sm);color:var(--__P__-fg-muted)}.__P__-tool-ask-input,.__P__-tool-approval{display:flex;flex-direction:column;gap:var(--__P__-space-2);margin-top:6px;padding:var(--__P__-space-3);border:1px solid var(--__P__-border);border-radius:var(--__P__-radius-md);background:var(--__P__-bg-elevated)}.__P__-tool-head{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.__P__-tool-badge{padding:2px 8px;border-radius:999px;background:var(--__P__-warning, #f59e0b);color:#1a1206;font-size:var(--__P__-text-xs);font-weight:600}.__P__-tool-title{font-size:var(--__P__-text-sm);color:var(--__P__-fg)}.__P__-tool-question{margin:0;font-size:var(--__P__-text-sm);font-weight:600;color:var(--__P__-fg)}.__P__-tool-desc{margin:0;font-size:var(--__P__-text-sm);color:var(--__P__-fg-muted)}.__P__-tool-args{margin:0;padding:var(--__P__-space-2);max-height:160px;overflow:auto;border-radius:var(--__P__-radius-sm);background:var(--__P__-bg);border:1px solid var(--__P__-border);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);white-space:pre-wrap;word-break:break-word}.__P__-tool-stale-note{margin:0;font-size:var(--__P__-text-xs);color:var(--__P__-fg-muted)}.__P__-tool-decided{flex-direction:row;align-items:center;flex-wrap:wrap;gap:8px}.__P__-tool-decided-label{padding:2px 8px;border-radius:999px;background:var(--__P__-bg);border:1px solid var(--__P__-border);color:var(--__P__-fg-muted);font-size:var(--__P__-text-xs);font-weight:600}.__P__-tool-decided-label[data-approved=true]{color:var(--__P__-success, #16a34a);border-color:var(--__P__-success, #16a34a)}.__P__-tool-decided-label[data-approved=false]{color:var(--__P__-danger);border-color:var(--__P__-danger)}.__P__-tool-decided-value{font-size:var(--__P__-text-sm);color:var(--__P__-fg)}\n';
|
|
716
874
|
|
|
717
875
|
// src/styles/standalone.css
|
|
718
876
|
var standalone_default = ".__P__-standalone-page{margin:0;height:100vh;background:var(--__P__-bg, #fff);display:grid;place-items:stretch}\n";
|
|
@@ -800,22 +958,22 @@ function attachAdoptedSheet(shadow, doc) {
|
|
|
800
958
|
}
|
|
801
959
|
}
|
|
802
960
|
function applyThemeOverrides(host, overrides) {
|
|
803
|
-
const
|
|
804
|
-
if (overrides.accent) host.style.setProperty(`--${
|
|
805
|
-
if (overrides.accentText) host.style.setProperty(`--${
|
|
806
|
-
if (overrides.radius) host.style.setProperty(`--${
|
|
807
|
-
if (overrides.fontFamily) host.style.setProperty(`--${
|
|
961
|
+
const p33 = BRAND.cssPrefix;
|
|
962
|
+
if (overrides.accent) host.style.setProperty(`--${p33}-accent`, overrides.accent);
|
|
963
|
+
if (overrides.accentText) host.style.setProperty(`--${p33}-accent-text`, overrides.accentText);
|
|
964
|
+
if (overrides.radius) host.style.setProperty(`--${p33}-radius`, overrides.radius);
|
|
965
|
+
if (overrides.fontFamily) host.style.setProperty(`--${p33}-font`, overrides.fontFamily);
|
|
808
966
|
}
|
|
809
967
|
function applyThemeMode(host, mode) {
|
|
810
968
|
host.dataset.theme = mode;
|
|
811
969
|
}
|
|
812
970
|
function applySize(host, size) {
|
|
813
|
-
const
|
|
814
|
-
if (size.width !== void 0) host.style.setProperty(`--${
|
|
815
|
-
if (size.height !== void 0) host.style.setProperty(`--${
|
|
816
|
-
if (size.expanded?.width !== void 0) host.style.setProperty(`--${
|
|
817
|
-
if (size.expanded?.height !== void 0) host.style.setProperty(`--${
|
|
818
|
-
if (size.inset !== void 0) host.style.setProperty(`--${
|
|
971
|
+
const p33 = BRAND.cssPrefix;
|
|
972
|
+
if (size.width !== void 0) host.style.setProperty(`--${p33}-panel-w`, size.width);
|
|
973
|
+
if (size.height !== void 0) host.style.setProperty(`--${p33}-panel-h`, size.height);
|
|
974
|
+
if (size.expanded?.width !== void 0) host.style.setProperty(`--${p33}-expanded-w`, size.expanded.width);
|
|
975
|
+
if (size.expanded?.height !== void 0) host.style.setProperty(`--${p33}-expanded-h`, size.expanded.height);
|
|
976
|
+
if (size.inset !== void 0) host.style.setProperty(`--${p33}-panel-inset`, size.inset);
|
|
819
977
|
}
|
|
820
978
|
function applyPosition(host, pos) {
|
|
821
979
|
host.dataset.position = pos;
|
|
@@ -986,11 +1144,11 @@ function toBase64Url(json) {
|
|
|
986
1144
|
var nonEmpty = (ctx) => ctx && Object.keys(ctx).length > 0 ? ctx : void 0;
|
|
987
1145
|
function encodeContext(user, page) {
|
|
988
1146
|
const u = nonEmpty(user);
|
|
989
|
-
const
|
|
990
|
-
if (!u && !
|
|
1147
|
+
const p33 = nonEmpty(page);
|
|
1148
|
+
if (!u && !p33) return void 0;
|
|
991
1149
|
const envelope = {};
|
|
992
1150
|
if (u) envelope.user = u;
|
|
993
|
-
if (
|
|
1151
|
+
if (p33) envelope.page = p33;
|
|
994
1152
|
return toBase64Url(JSON.stringify(envelope));
|
|
995
1153
|
}
|
|
996
1154
|
|
|
@@ -1029,7 +1187,15 @@ var DEFAULT_PATHS = {
|
|
|
1029
1187
|
markRead: "/ai/agent/mark-read",
|
|
1030
1188
|
// ── CMS content (unified — Home / Help / News / docs) ─────────────
|
|
1031
1189
|
/** All widget content via one filtered endpoint. `GET /ai/agent/content?tags=…`. */
|
|
1032
|
-
content: "/ai/agent/content"
|
|
1190
|
+
content: "/ai/agent/content",
|
|
1191
|
+
/**
|
|
1192
|
+
* Optional pre-chat intake submission. POST `{ visitorId, sessionId, values,
|
|
1193
|
+
* skipped? }` → record the lead immediately (before/independent of the first
|
|
1194
|
+
* message), keyed by the same visitor + session as the conversation.
|
|
1195
|
+
* Overridable via `endpoints.intake`. Fire-and-forget; 404 on older backends
|
|
1196
|
+
* is ignored.
|
|
1197
|
+
*/
|
|
1198
|
+
intake: "/ai/agent/intake"
|
|
1033
1199
|
};
|
|
1034
1200
|
var CONTEXT_PARAM = "context";
|
|
1035
1201
|
function buildSendMessageRequest(params) {
|
|
@@ -1053,18 +1219,34 @@ function buildSendMessageRequest(params) {
|
|
|
1053
1219
|
if (Object.keys(data).length > 0) body.data = data;
|
|
1054
1220
|
return body;
|
|
1055
1221
|
}
|
|
1222
|
+
function isResolvedToolPart(p33) {
|
|
1223
|
+
return p33.state === "output" || p33.state === "error" || p33.approval?.approved !== void 0;
|
|
1224
|
+
}
|
|
1056
1225
|
function normalizeToolRef(ref) {
|
|
1057
1226
|
if (typeof ref === "string") return ref ? { code: ref } : null;
|
|
1058
1227
|
return ref?.code ? ref : null;
|
|
1059
1228
|
}
|
|
1060
1229
|
function messageToWireParts(m) {
|
|
1061
1230
|
const out = [];
|
|
1062
|
-
for (const
|
|
1063
|
-
if (
|
|
1064
|
-
out.push({ text:
|
|
1231
|
+
for (const p33 of m.parts) {
|
|
1232
|
+
if (p33.kind === "text" && p33.text) {
|
|
1233
|
+
out.push({ text: p33.text, type: "text" });
|
|
1065
1234
|
}
|
|
1066
|
-
if (
|
|
1067
|
-
out.push({ mediaType:
|
|
1235
|
+
if (p33.kind === "file" && p33.url) {
|
|
1236
|
+
out.push({ mediaType: p33.mediaType, type: "file", url: p33.url });
|
|
1237
|
+
}
|
|
1238
|
+
if (p33.kind === "tool" && isResolvedToolPart(p33)) {
|
|
1239
|
+
const part = {
|
|
1240
|
+
type: "tool",
|
|
1241
|
+
toolCallId: p33.toolCallId,
|
|
1242
|
+
toolName: p33.toolName,
|
|
1243
|
+
state: p33.state
|
|
1244
|
+
};
|
|
1245
|
+
if (p33.input !== void 0) part.input = p33.input;
|
|
1246
|
+
if (p33.output !== void 0) part.output = p33.output;
|
|
1247
|
+
if (p33.error !== void 0) part.errorText = p33.error;
|
|
1248
|
+
if (p33.approval && p33.approval.approved !== void 0) part.approval = p33.approval;
|
|
1249
|
+
out.push(part);
|
|
1068
1250
|
}
|
|
1069
1251
|
}
|
|
1070
1252
|
for (const a of m.attachments ?? []) {
|
|
@@ -1311,6 +1493,25 @@ var AgentTransport = class {
|
|
|
1311
1493
|
get transcribePath() {
|
|
1312
1494
|
return this.opts.endpoints?.transcribe ?? "/ai/agent/transcribe-audio";
|
|
1313
1495
|
}
|
|
1496
|
+
get intakePath() {
|
|
1497
|
+
return this.opts.endpoints?.intake ?? DEFAULT_PATHS.intake;
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Record a completed pre-chat intake form. Fire-and-forget — the lead is
|
|
1501
|
+
* captured even if the visitor never sends a message. `sessionId` is explicit
|
|
1502
|
+
* so the record ties to the conversation that follows; `visitorId` + context
|
|
1503
|
+
* ride the envelope. A failure (e.g. 404 on a backend that doesn't implement
|
|
1504
|
+
* the endpoint) is non-fatal — the values still reach the agent as
|
|
1505
|
+
* `userContext` on the next message, so callers don't await this.
|
|
1506
|
+
*/
|
|
1507
|
+
async submitIntake(sessionId, values, skipped = false) {
|
|
1508
|
+
log4.debug("submitIntake \u2192", { sessionId, fields: Object.keys(values).length, skipped });
|
|
1509
|
+
try {
|
|
1510
|
+
await this.postJson(this.intakePath, { sessionId, values, skipped }, "submitIntake");
|
|
1511
|
+
} catch (err) {
|
|
1512
|
+
log4.debug("submitIntake failed (non-fatal)", { err });
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1314
1515
|
sendMessage(body) {
|
|
1315
1516
|
log4.debug("message \u2192", {
|
|
1316
1517
|
sessionId: body.sessionId,
|
|
@@ -1624,8 +1825,21 @@ function fromWireMessage(w) {
|
|
|
1624
1825
|
if (part.type === "file") {
|
|
1625
1826
|
return { kind: "file", url: part.url, mediaType: part.mediaType };
|
|
1626
1827
|
}
|
|
1828
|
+
if (part.type === "tool") {
|
|
1829
|
+
return {
|
|
1830
|
+
kind: "tool",
|
|
1831
|
+
toolCallId: part.toolCallId,
|
|
1832
|
+
toolName: part.toolName,
|
|
1833
|
+
inputPartialSig: signal(""),
|
|
1834
|
+
inputSig: signal(part.input),
|
|
1835
|
+
outputSig: signal(part.output),
|
|
1836
|
+
errorSig: signal(part.errorText),
|
|
1837
|
+
stateSig: signal(part.state),
|
|
1838
|
+
approvalSig: signal(part.approval)
|
|
1839
|
+
};
|
|
1840
|
+
}
|
|
1627
1841
|
return null;
|
|
1628
|
-
}).filter((
|
|
1842
|
+
}).filter((p33) => p33 !== null);
|
|
1629
1843
|
return {
|
|
1630
1844
|
id: w.id,
|
|
1631
1845
|
role: w.role,
|
|
@@ -1655,45 +1869,60 @@ function assistantText(m) {
|
|
|
1655
1869
|
}
|
|
1656
1870
|
return out;
|
|
1657
1871
|
}
|
|
1658
|
-
function partToReactive(
|
|
1659
|
-
if (
|
|
1660
|
-
return { kind:
|
|
1872
|
+
function partToReactive(p33) {
|
|
1873
|
+
if (p33.kind === "text" || p33.kind === "reasoning") {
|
|
1874
|
+
return { kind: p33.kind, id: p33.id, textSig: signal(p33.text), doneSig: signal(p33.done) };
|
|
1661
1875
|
}
|
|
1662
|
-
if (
|
|
1876
|
+
if (p33.kind === "tool") {
|
|
1663
1877
|
return {
|
|
1664
1878
|
kind: "tool",
|
|
1665
|
-
toolCallId:
|
|
1666
|
-
toolName:
|
|
1667
|
-
inputPartialSig: signal(
|
|
1668
|
-
inputSig: signal(
|
|
1669
|
-
outputSig: signal(
|
|
1670
|
-
errorSig: signal(
|
|
1671
|
-
stateSig: signal(
|
|
1879
|
+
toolCallId: p33.toolCallId,
|
|
1880
|
+
toolName: p33.toolName,
|
|
1881
|
+
inputPartialSig: signal(p33.inputPartial),
|
|
1882
|
+
inputSig: signal(p33.input),
|
|
1883
|
+
outputSig: signal(p33.output),
|
|
1884
|
+
errorSig: signal(p33.error),
|
|
1885
|
+
stateSig: signal(p33.state),
|
|
1886
|
+
approvalSig: signal(p33.approval)
|
|
1672
1887
|
};
|
|
1673
1888
|
}
|
|
1674
|
-
return
|
|
1889
|
+
return p33;
|
|
1675
1890
|
}
|
|
1676
|
-
function partFromReactive(
|
|
1677
|
-
if (
|
|
1678
|
-
return { kind:
|
|
1891
|
+
function partFromReactive(p33) {
|
|
1892
|
+
if (p33.kind === "text" || p33.kind === "reasoning") {
|
|
1893
|
+
return { kind: p33.kind, id: p33.id, text: p33.textSig.value, done: p33.doneSig.value };
|
|
1679
1894
|
}
|
|
1680
|
-
if (
|
|
1895
|
+
if (p33.kind === "tool") {
|
|
1681
1896
|
return {
|
|
1682
1897
|
kind: "tool",
|
|
1683
|
-
toolCallId:
|
|
1684
|
-
toolName:
|
|
1685
|
-
inputPartial:
|
|
1686
|
-
input:
|
|
1687
|
-
output:
|
|
1688
|
-
error:
|
|
1689
|
-
state:
|
|
1898
|
+
toolCallId: p33.toolCallId,
|
|
1899
|
+
toolName: p33.toolName,
|
|
1900
|
+
inputPartial: p33.inputPartialSig.value,
|
|
1901
|
+
input: p33.inputSig.value,
|
|
1902
|
+
output: p33.outputSig.value,
|
|
1903
|
+
error: p33.errorSig.value,
|
|
1904
|
+
state: p33.stateSig.value,
|
|
1905
|
+
approval: p33.approvalSig.value
|
|
1690
1906
|
};
|
|
1691
1907
|
}
|
|
1692
|
-
return
|
|
1908
|
+
return p33;
|
|
1693
1909
|
}
|
|
1694
1910
|
|
|
1695
1911
|
// src/stream/reducer.ts
|
|
1696
1912
|
import { signal as signal2 } from "@preact/signals";
|
|
1913
|
+
|
|
1914
|
+
// src/stream/constants.ts
|
|
1915
|
+
var ASK_USER_INPUT_TOOL = "tool:ask-user-input";
|
|
1916
|
+
function isAskUserInputTool(toolName) {
|
|
1917
|
+
return toolName === ASK_USER_INPUT_TOOL;
|
|
1918
|
+
}
|
|
1919
|
+
var TRIGGER = {
|
|
1920
|
+
submitMessage: "submit-message",
|
|
1921
|
+
toolResult: "tool-result",
|
|
1922
|
+
toolApproval: "tool-approval"
|
|
1923
|
+
};
|
|
1924
|
+
|
|
1925
|
+
// src/stream/reducer.ts
|
|
1697
1926
|
var log5 = logger.scope("reducer");
|
|
1698
1927
|
var StreamReducer = class {
|
|
1699
1928
|
constructor(messagesSig) {
|
|
@@ -1731,8 +1960,8 @@ var StreamReducer = class {
|
|
|
1731
1960
|
ensureTextPart(m, "text", chunk.id);
|
|
1732
1961
|
return;
|
|
1733
1962
|
case "text-delta": {
|
|
1734
|
-
const
|
|
1735
|
-
|
|
1963
|
+
const p33 = ensureTextPart(m, "text", chunk.id);
|
|
1964
|
+
p33.textSig.value += chunk.delta;
|
|
1736
1965
|
return;
|
|
1737
1966
|
}
|
|
1738
1967
|
case "text-end":
|
|
@@ -1742,8 +1971,8 @@ var StreamReducer = class {
|
|
|
1742
1971
|
ensureTextPart(m, "reasoning", chunk.id).doneSig.value = false;
|
|
1743
1972
|
return;
|
|
1744
1973
|
case "reasoning-delta": {
|
|
1745
|
-
const
|
|
1746
|
-
|
|
1974
|
+
const p33 = ensureTextPart(m, "reasoning", chunk.id);
|
|
1975
|
+
p33.textSig.value += chunk.delta;
|
|
1747
1976
|
return;
|
|
1748
1977
|
}
|
|
1749
1978
|
case "reasoning-end":
|
|
@@ -1754,6 +1983,7 @@ var StreamReducer = class {
|
|
|
1754
1983
|
case "tool-input-available":
|
|
1755
1984
|
case "tool-output-available":
|
|
1756
1985
|
case "tool-output-error":
|
|
1986
|
+
case "tool-approval-request":
|
|
1757
1987
|
applyTool(m, chunk);
|
|
1758
1988
|
return;
|
|
1759
1989
|
case "file":
|
|
@@ -1761,7 +1991,7 @@ var StreamReducer = class {
|
|
|
1761
1991
|
return;
|
|
1762
1992
|
case "source-url": {
|
|
1763
1993
|
const parts = m.partsSig.value;
|
|
1764
|
-
if (parts.some((
|
|
1994
|
+
if (parts.some((p33) => p33.kind === "source" && p33.sourceId === chunk.sourceId)) return;
|
|
1765
1995
|
appendPart(m, { kind: "source", sourceId: chunk.sourceId, url: chunk.url, title: chunk.title });
|
|
1766
1996
|
return;
|
|
1767
1997
|
}
|
|
@@ -1785,14 +2015,14 @@ var StreamReducer = class {
|
|
|
1785
2015
|
}
|
|
1786
2016
|
};
|
|
1787
2017
|
function ensureTextPart(m, kind, id) {
|
|
1788
|
-
const existing = m.partsSig.value.find((
|
|
2018
|
+
const existing = m.partsSig.value.find((p33) => p33.kind === kind && p33.id === id);
|
|
1789
2019
|
if (existing) return existing;
|
|
1790
2020
|
const part = { kind, id, textSig: signal2(""), doneSig: signal2(false) };
|
|
1791
2021
|
appendPart(m, part);
|
|
1792
2022
|
return part;
|
|
1793
2023
|
}
|
|
1794
2024
|
function ensureToolPart(m, toolCallId, toolName) {
|
|
1795
|
-
const existing = m.partsSig.value.find((
|
|
2025
|
+
const existing = m.partsSig.value.find((p33) => p33.kind === "tool" && p33.toolCallId === toolCallId);
|
|
1796
2026
|
if (existing) return existing;
|
|
1797
2027
|
const part = {
|
|
1798
2028
|
kind: "tool",
|
|
@@ -1802,7 +2032,8 @@ function ensureToolPart(m, toolCallId, toolName) {
|
|
|
1802
2032
|
inputSig: signal2(void 0),
|
|
1803
2033
|
outputSig: signal2(void 0),
|
|
1804
2034
|
errorSig: signal2(void 0),
|
|
1805
|
-
stateSig: signal2("input")
|
|
2035
|
+
stateSig: signal2("input"),
|
|
2036
|
+
approvalSig: signal2(void 0)
|
|
1806
2037
|
};
|
|
1807
2038
|
appendPart(m, part);
|
|
1808
2039
|
return part;
|
|
@@ -1816,26 +2047,32 @@ function applyTool(m, chunk) {
|
|
|
1816
2047
|
ensureToolPart(m, chunk.toolCallId, chunk.toolName);
|
|
1817
2048
|
return;
|
|
1818
2049
|
case "tool-input-delta": {
|
|
1819
|
-
const
|
|
1820
|
-
|
|
2050
|
+
const p33 = ensureToolPart(m, chunk.toolCallId);
|
|
2051
|
+
p33.inputPartialSig.value += chunk.delta;
|
|
1821
2052
|
return;
|
|
1822
2053
|
}
|
|
1823
2054
|
case "tool-input-available": {
|
|
1824
|
-
const
|
|
1825
|
-
|
|
1826
|
-
|
|
2055
|
+
const p33 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
|
|
2056
|
+
p33.inputSig.value = chunk.input;
|
|
2057
|
+
p33.stateSig.value = isAskUserInputTool(p33.toolName) ? "awaiting-input" : "awaiting";
|
|
2058
|
+
return;
|
|
2059
|
+
}
|
|
2060
|
+
case "tool-approval-request": {
|
|
2061
|
+
const p33 = ensureToolPart(m, chunk.toolCallId, chunk.toolName);
|
|
2062
|
+
p33.approvalSig.value = { id: chunk.approvalId };
|
|
2063
|
+
p33.stateSig.value = "awaiting-approval";
|
|
1827
2064
|
return;
|
|
1828
2065
|
}
|
|
1829
2066
|
case "tool-output-available": {
|
|
1830
|
-
const
|
|
1831
|
-
|
|
1832
|
-
|
|
2067
|
+
const p33 = ensureToolPart(m, chunk.toolCallId);
|
|
2068
|
+
p33.outputSig.value = chunk.output;
|
|
2069
|
+
p33.stateSig.value = "output";
|
|
1833
2070
|
return;
|
|
1834
2071
|
}
|
|
1835
2072
|
case "tool-output-error": {
|
|
1836
|
-
const
|
|
1837
|
-
|
|
1838
|
-
|
|
2073
|
+
const p33 = ensureToolPart(m, chunk.toolCallId);
|
|
2074
|
+
p33.errorSig.value = chunk.errorText;
|
|
2075
|
+
p33.stateSig.value = "error";
|
|
1839
2076
|
return;
|
|
1840
2077
|
}
|
|
1841
2078
|
default:
|
|
@@ -1855,6 +2092,7 @@ function createPersistence(widgetId, storage = defaultStorage) {
|
|
|
1855
2092
|
const KEY_CALLOUT_DISMISSED = `${prefix}.calloutDismissed`;
|
|
1856
2093
|
const KEY_SIDEBAR_COLLAPSED = `${prefix}.sidebarCollapsed`;
|
|
1857
2094
|
const KEY_ACTIVE_MODULE = `${prefix}.activeModule`;
|
|
2095
|
+
const KEY_INTAKE = `${prefix}.intake`;
|
|
1858
2096
|
const persistence = {
|
|
1859
2097
|
getVisitorId() {
|
|
1860
2098
|
const existing = storage.get(KEY_VISITOR);
|
|
@@ -1937,6 +2175,24 @@ function createPersistence(widgetId, storage = defaultStorage) {
|
|
|
1937
2175
|
saveActiveModule(id) {
|
|
1938
2176
|
storage.set(KEY_ACTIVE_MODULE, id);
|
|
1939
2177
|
},
|
|
2178
|
+
loadIntake() {
|
|
2179
|
+
const raw = storage.get(KEY_INTAKE);
|
|
2180
|
+
if (!raw) return null;
|
|
2181
|
+
try {
|
|
2182
|
+
const parsed = JSON.parse(raw);
|
|
2183
|
+
return isPlainObject2(parsed) ? parsed : null;
|
|
2184
|
+
} catch (error) {
|
|
2185
|
+
log6.warn("loadIntake parse failed", { error });
|
|
2186
|
+
return null;
|
|
2187
|
+
}
|
|
2188
|
+
},
|
|
2189
|
+
saveIntake(values) {
|
|
2190
|
+
try {
|
|
2191
|
+
storage.set(KEY_INTAKE, JSON.stringify(values));
|
|
2192
|
+
} catch (error) {
|
|
2193
|
+
log6.warn("saveIntake serialise failed", { error });
|
|
2194
|
+
}
|
|
2195
|
+
},
|
|
1940
2196
|
clearSession() {
|
|
1941
2197
|
storage.remove(KEY_CHAT);
|
|
1942
2198
|
}
|
|
@@ -2478,7 +2734,30 @@ var TID = {
|
|
|
2478
2734
|
/** Help article row — suffix `-{id}`. */
|
|
2479
2735
|
helpArticle: `${p2}-help-article`,
|
|
2480
2736
|
/** News list item — suffix `-{id}`. */
|
|
2481
|
-
newsItem: `${p2}-news-item
|
|
2737
|
+
newsItem: `${p2}-news-item`,
|
|
2738
|
+
// ── Forms + human-in-the-loop (intake / ask-input / approval) ────
|
|
2739
|
+
/** Pre-chat intake form root (blocking gate). */
|
|
2740
|
+
intakeForm: `${p2}-intake-form`,
|
|
2741
|
+
/** Intake submit button. */
|
|
2742
|
+
intakeSubmit: `${p2}-intake-submit`,
|
|
2743
|
+
/** Intake skip button (only when `skippable`). */
|
|
2744
|
+
intakeSkip: `${p2}-intake-skip`,
|
|
2745
|
+
/** A single form field control — suffix `-{name}` at the JSX site. */
|
|
2746
|
+
formField: `${p2}-form-field`,
|
|
2747
|
+
/** Ask-input tool root (inline form in a message bubble). */
|
|
2748
|
+
toolAskInput: `${p2}-tool-ask-input`,
|
|
2749
|
+
/** Ask-input submit button. */
|
|
2750
|
+
toolInputSubmit: `${p2}-tool-input-submit`,
|
|
2751
|
+
/** Ask-input skip button. */
|
|
2752
|
+
toolInputSkip: `${p2}-tool-input-skip`,
|
|
2753
|
+
/** Tool-approval root (approve/reject prompt). */
|
|
2754
|
+
toolApproval: `${p2}-tool-approval`,
|
|
2755
|
+
/** Tool-approval approve button. */
|
|
2756
|
+
toolApprove: `${p2}-tool-approve`,
|
|
2757
|
+
/** Tool-approval reject button. */
|
|
2758
|
+
toolReject: `${p2}-tool-reject`,
|
|
2759
|
+
/** Recorded tool decision summary (after approve/reject/submit). */
|
|
2760
|
+
toolDecision: `${p2}-tool-decision`
|
|
2482
2761
|
};
|
|
2483
2762
|
function tid(base, suffix) {
|
|
2484
2763
|
return `${base}-${suffix}`;
|
|
@@ -2589,24 +2868,24 @@ import { useCallback as useCallback2, useEffect as useEffect10, useRef as useRef
|
|
|
2589
2868
|
import { useEffect as useEffect2, useRef } from "preact/hooks";
|
|
2590
2869
|
import { jsx as jsx3 } from "preact/jsx-runtime";
|
|
2591
2870
|
function ResizeGrip({ panelEl, resize, position, initialSize, onSizeChange, strings }) {
|
|
2592
|
-
const
|
|
2871
|
+
const p33 = BRAND.cssPrefix;
|
|
2593
2872
|
const dragRef = useRef(null);
|
|
2594
2873
|
useEffect2(() => {
|
|
2595
2874
|
if (!panelEl) return;
|
|
2596
2875
|
const style = panelEl.style;
|
|
2597
|
-
if (resize.minWidth) style.setProperty(`--${
|
|
2598
|
-
if (resize.maxWidth) style.setProperty(`--${
|
|
2599
|
-
if (resize.minHeight) style.setProperty(`--${
|
|
2600
|
-
if (resize.maxHeight) style.setProperty(`--${
|
|
2876
|
+
if (resize.minWidth) style.setProperty(`--${p33}-resize-min-w`, resize.minWidth);
|
|
2877
|
+
if (resize.maxWidth) style.setProperty(`--${p33}-resize-max-w`, resize.maxWidth);
|
|
2878
|
+
if (resize.minHeight) style.setProperty(`--${p33}-resize-min-h`, resize.minHeight);
|
|
2879
|
+
if (resize.maxHeight) style.setProperty(`--${p33}-resize-max-h`, resize.maxHeight);
|
|
2601
2880
|
if (initialSize) {
|
|
2602
|
-
style.setProperty(`--${
|
|
2603
|
-
style.setProperty(`--${
|
|
2881
|
+
style.setProperty(`--${p33}-widget-w`, `${initialSize.width}px`);
|
|
2882
|
+
style.setProperty(`--${p33}-widget-h`, `${initialSize.height}px`);
|
|
2604
2883
|
}
|
|
2605
|
-
}, [panelEl, resize.minWidth, resize.maxWidth, resize.minHeight, resize.maxHeight,
|
|
2884
|
+
}, [panelEl, resize.minWidth, resize.maxWidth, resize.minHeight, resize.maxHeight, p33, initialSize]);
|
|
2606
2885
|
if (!panelEl) return null;
|
|
2607
2886
|
const isTop = position.startsWith("top-");
|
|
2608
2887
|
const isRight = position.endsWith("-right");
|
|
2609
|
-
const cornerClass = `${
|
|
2888
|
+
const cornerClass = `${p33}-resize-grip ${p33}-resize-grip--${isTop ? "bottom" : "top"}-${isRight ? "left" : "right"}`;
|
|
2610
2889
|
const onPointerDown = (e) => {
|
|
2611
2890
|
if (!panelEl) return;
|
|
2612
2891
|
const target = e.currentTarget;
|
|
@@ -2630,8 +2909,8 @@ function ResizeGrip({ panelEl, resize, position, initialSize, onSizeChange, stri
|
|
|
2630
2909
|
if (!d || e.pointerId !== d.pointerId || !panelEl) return;
|
|
2631
2910
|
const dx = (e.clientX - d.startX) * d.dirX;
|
|
2632
2911
|
const dy = (e.clientY - d.startY) * d.dirY;
|
|
2633
|
-
panelEl.style.setProperty(`--${
|
|
2634
|
-
panelEl.style.setProperty(`--${
|
|
2912
|
+
panelEl.style.setProperty(`--${p33}-widget-w`, `${d.startW + dx}px`);
|
|
2913
|
+
panelEl.style.setProperty(`--${p33}-widget-h`, `${d.startH + dy}px`);
|
|
2635
2914
|
};
|
|
2636
2915
|
const onPointerUp = (e) => {
|
|
2637
2916
|
const d = dragRef.current;
|
|
@@ -2668,7 +2947,7 @@ var KEEP_VISIBLE = 56;
|
|
|
2668
2947
|
function useDragMove(panelEl, enabled) {
|
|
2669
2948
|
useEffect3(() => {
|
|
2670
2949
|
if (!enabled || !panelEl) return;
|
|
2671
|
-
const
|
|
2950
|
+
const num2 = (v) => Number.parseFloat(v) || 0;
|
|
2672
2951
|
const clamp = (v, max) => Math.min(max, Math.max(-max, v));
|
|
2673
2952
|
let drag = null;
|
|
2674
2953
|
const onDown = (e) => {
|
|
@@ -2679,8 +2958,8 @@ function useDragMove(panelEl, enabled) {
|
|
|
2679
2958
|
id: e.pointerId,
|
|
2680
2959
|
x: e.clientX,
|
|
2681
2960
|
y: e.clientY,
|
|
2682
|
-
dx:
|
|
2683
|
-
dy:
|
|
2961
|
+
dx: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dx`)),
|
|
2962
|
+
dy: num2(panelEl.style.getPropertyValue(`--${p4}-modal-dy`)),
|
|
2684
2963
|
// Centred origin: |offset| ≤ (viewport + panel)/2 − keepVisible keeps a
|
|
2685
2964
|
// strip of the dialog reachable so it can never be lost off-screen.
|
|
2686
2965
|
maxX: (window.innerWidth + rect.width) / 2 - KEEP_VISIBLE,
|
|
@@ -3366,20 +3645,20 @@ function usePopoverMenu({ itemCount, initialFocusIndex }) {
|
|
|
3366
3645
|
// src/ui/overflow-menu.tsx
|
|
3367
3646
|
import { jsx as jsx8, jsxs as jsxs6 } from "preact/jsx-runtime";
|
|
3368
3647
|
function OverflowMenu({ items, triggerLabel }) {
|
|
3369
|
-
const
|
|
3648
|
+
const p33 = BRAND.cssPrefix;
|
|
3370
3649
|
const menu = usePopoverMenu({ itemCount: items.length });
|
|
3371
3650
|
const handleSelect = (item) => {
|
|
3372
3651
|
if (item.disabled) return;
|
|
3373
3652
|
item.onSelect();
|
|
3374
3653
|
if (!item.keepOpen) menu.close();
|
|
3375
3654
|
};
|
|
3376
|
-
return /* @__PURE__ */ jsxs6("div", { class: `${
|
|
3655
|
+
return /* @__PURE__ */ jsxs6("div", { class: `${p33}-menu-wrap`, children: [
|
|
3377
3656
|
/* @__PURE__ */ jsx8(
|
|
3378
3657
|
"button",
|
|
3379
3658
|
{
|
|
3380
3659
|
ref: menu.triggerRef,
|
|
3381
3660
|
type: "button",
|
|
3382
|
-
class: `${
|
|
3661
|
+
class: `${p33}-icon-btn`,
|
|
3383
3662
|
"aria-label": triggerLabel,
|
|
3384
3663
|
"aria-haspopup": "menu",
|
|
3385
3664
|
"aria-expanded": menu.open,
|
|
@@ -3393,7 +3672,7 @@ function OverflowMenu({ items, triggerLabel }) {
|
|
|
3393
3672
|
"div",
|
|
3394
3673
|
{
|
|
3395
3674
|
ref: menu.menuRef,
|
|
3396
|
-
class: `${
|
|
3675
|
+
class: `${p33}-menu`,
|
|
3397
3676
|
role: "menu",
|
|
3398
3677
|
"aria-label": triggerLabel,
|
|
3399
3678
|
onKeyDown: menu.onMenuKey,
|
|
@@ -3403,15 +3682,15 @@ function OverflowMenu({ items, triggerLabel }) {
|
|
|
3403
3682
|
{
|
|
3404
3683
|
type: "button",
|
|
3405
3684
|
role: "menuitem",
|
|
3406
|
-
class: `${
|
|
3685
|
+
class: `${p33}-menu-item`,
|
|
3407
3686
|
"aria-pressed": item.type === "switch" ? item.on : void 0,
|
|
3408
3687
|
disabled: item.disabled,
|
|
3409
3688
|
lang: item.lang,
|
|
3410
3689
|
onClick: () => handleSelect(item),
|
|
3411
3690
|
children: [
|
|
3412
|
-
item.icon ? /* @__PURE__ */ jsx8("span", { class: `${
|
|
3413
|
-
/* @__PURE__ */ jsx8("span", { class: `${
|
|
3414
|
-
item.type === "switch" && item.on ? /* @__PURE__ */ jsx8("span", { class: `${
|
|
3691
|
+
item.icon ? /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-icon`, children: item.icon }) : null,
|
|
3692
|
+
/* @__PURE__ */ jsx8("span", { class: `${p33}-menu-label`, children: item.label }),
|
|
3693
|
+
item.type === "switch" && item.on ? /* @__PURE__ */ jsx8("span", { class: `${p33}-menu-check`, "aria-hidden": "true", children: /* @__PURE__ */ jsx8(CheckIcon, {}) }) : null
|
|
3415
3694
|
]
|
|
3416
3695
|
},
|
|
3417
3696
|
item.id
|
|
@@ -3533,18 +3812,360 @@ function HeaderActions({ panelProps, variant }) {
|
|
|
3533
3812
|
] });
|
|
3534
3813
|
}
|
|
3535
3814
|
|
|
3815
|
+
// src/ui/form/dynamic-form.tsx
|
|
3816
|
+
import { useState as useState5 } from "preact/hooks";
|
|
3817
|
+
|
|
3818
|
+
// src/ui/form/validate.ts
|
|
3819
|
+
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
3820
|
+
var URL_RE = /^https?:\/\/[^\s.]+\.[^\s]+$/i;
|
|
3821
|
+
var TEL_RE = /^[+]?[\d\s().-]{6,}$/;
|
|
3822
|
+
function fmt(template, vars) {
|
|
3823
|
+
return template.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? `{${k}}`));
|
|
3824
|
+
}
|
|
3825
|
+
function selectionCount(value) {
|
|
3826
|
+
if (Array.isArray(value)) return value.length;
|
|
3827
|
+
return value && value.trim() ? 1 : 0;
|
|
3828
|
+
}
|
|
3829
|
+
function validateField(field, value, strings) {
|
|
3830
|
+
const required = field.required ?? true;
|
|
3831
|
+
const v = field.validation;
|
|
3832
|
+
if (field.type === "multiselect") {
|
|
3833
|
+
const count = selectionCount(value);
|
|
3834
|
+
if (required && count === 0) return strings.formRequired;
|
|
3835
|
+
if (count === 0) return void 0;
|
|
3836
|
+
if (v?.minSelections != null && count < v.minSelections) {
|
|
3837
|
+
return fmt(strings.formChooseAtLeast, { min: v.minSelections });
|
|
3838
|
+
}
|
|
3839
|
+
if (v?.maxSelections != null && count > v.maxSelections) {
|
|
3840
|
+
return fmt(strings.formChooseAtMost, { max: v.maxSelections });
|
|
3841
|
+
}
|
|
3842
|
+
return void 0;
|
|
3843
|
+
}
|
|
3844
|
+
const text = typeof value === "string" ? value.trim() : "";
|
|
3845
|
+
if (!text) return required ? strings.formRequired : void 0;
|
|
3846
|
+
switch (field.type) {
|
|
3847
|
+
case "email":
|
|
3848
|
+
if (!EMAIL_RE2.test(text)) return strings.formInvalidEmail;
|
|
3849
|
+
break;
|
|
3850
|
+
case "url":
|
|
3851
|
+
if (!URL_RE.test(text)) return strings.formInvalidUrl;
|
|
3852
|
+
break;
|
|
3853
|
+
case "tel":
|
|
3854
|
+
if (!TEL_RE.test(text)) return strings.formInvalidTel;
|
|
3855
|
+
break;
|
|
3856
|
+
case "number": {
|
|
3857
|
+
const n = Number(text);
|
|
3858
|
+
if (!Number.isFinite(n)) return strings.formInvalidNumber;
|
|
3859
|
+
if (v?.min != null && n < v.min) return fmt(strings.formNumberTooSmall, { min: v.min });
|
|
3860
|
+
if (v?.max != null && n > v.max) return fmt(strings.formNumberTooLarge, { max: v.max });
|
|
3861
|
+
break;
|
|
3862
|
+
}
|
|
3863
|
+
default:
|
|
3864
|
+
break;
|
|
3865
|
+
}
|
|
3866
|
+
if (v?.minLength != null && text.length < v.minLength) return fmt(strings.formTooShort, { min: v.minLength });
|
|
3867
|
+
if (v?.maxLength != null && text.length > v.maxLength) return fmt(strings.formTooLong, { max: v.maxLength });
|
|
3868
|
+
if (v?.pattern) {
|
|
3869
|
+
try {
|
|
3870
|
+
if (!new RegExp(v.pattern).test(text)) return strings.formPatternMismatch;
|
|
3871
|
+
} catch {
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
return void 0;
|
|
3875
|
+
}
|
|
3876
|
+
function validateForm(fields, values, strings) {
|
|
3877
|
+
const errors = {};
|
|
3878
|
+
for (const field of fields) {
|
|
3879
|
+
const err = validateField(field, values[field.name], strings);
|
|
3880
|
+
if (err) errors[field.name] = err;
|
|
3881
|
+
}
|
|
3882
|
+
return errors;
|
|
3883
|
+
}
|
|
3884
|
+
function flattenValues(values) {
|
|
3885
|
+
const out = {};
|
|
3886
|
+
for (const [k, v] of Object.entries(values)) {
|
|
3887
|
+
const flat = Array.isArray(v) ? v.join(", ") : v;
|
|
3888
|
+
if (flat && flat.trim()) out[k] = flat.trim();
|
|
3889
|
+
}
|
|
3890
|
+
return out;
|
|
3891
|
+
}
|
|
3892
|
+
|
|
3893
|
+
// src/ui/form/dynamic-form.tsx
|
|
3894
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
3895
|
+
var p10 = BRAND.cssPrefix;
|
|
3896
|
+
var OTHER = "__other__";
|
|
3897
|
+
function DynamicForm({
|
|
3898
|
+
fields,
|
|
3899
|
+
strings,
|
|
3900
|
+
submitLabel,
|
|
3901
|
+
onSubmit,
|
|
3902
|
+
skipLabel,
|
|
3903
|
+
onSkip,
|
|
3904
|
+
disabled,
|
|
3905
|
+
rootTestId,
|
|
3906
|
+
submitTestId,
|
|
3907
|
+
skipTestId
|
|
3908
|
+
}) {
|
|
3909
|
+
const [values, setValues] = useState5(() => seedValues(fields));
|
|
3910
|
+
const [other, setOther] = useState5({});
|
|
3911
|
+
const [errors, setErrors] = useState5({});
|
|
3912
|
+
const clearError = (name) => {
|
|
3913
|
+
if (errors[name]) setErrors((prev) => ({ ...prev, [name]: "" }));
|
|
3914
|
+
};
|
|
3915
|
+
const setValue = (name, v) => {
|
|
3916
|
+
setValues((prev) => ({ ...prev, [name]: v }));
|
|
3917
|
+
clearError(name);
|
|
3918
|
+
};
|
|
3919
|
+
const setOtherText = (name, t) => {
|
|
3920
|
+
setOther((prev) => ({ ...prev, [name]: t }));
|
|
3921
|
+
clearError(name);
|
|
3922
|
+
};
|
|
3923
|
+
const submit = (e) => {
|
|
3924
|
+
e.preventDefault();
|
|
3925
|
+
if (disabled) return;
|
|
3926
|
+
const resolved = resolveValues(fields, values, other);
|
|
3927
|
+
const errs = validateForm(fields, resolved, strings);
|
|
3928
|
+
if (Object.keys(errs).length > 0) {
|
|
3929
|
+
setErrors(errs);
|
|
3930
|
+
return;
|
|
3931
|
+
}
|
|
3932
|
+
onSubmit(flattenValues(resolved));
|
|
3933
|
+
};
|
|
3934
|
+
return /* @__PURE__ */ jsxs8("form", { class: `${p10}-form`, onSubmit: submit, "data-testid": rootTestId, noValidate: true, children: [
|
|
3935
|
+
fields.map((field) => /* @__PURE__ */ jsx10(
|
|
3936
|
+
Field,
|
|
3937
|
+
{
|
|
3938
|
+
field,
|
|
3939
|
+
value: values[field.name],
|
|
3940
|
+
otherText: other[field.name] ?? "",
|
|
3941
|
+
error: errors[field.name],
|
|
3942
|
+
disabled,
|
|
3943
|
+
strings,
|
|
3944
|
+
onChange: (v) => setValue(field.name, v),
|
|
3945
|
+
onOtherChange: (t) => setOtherText(field.name, t)
|
|
3946
|
+
},
|
|
3947
|
+
field.name
|
|
3948
|
+
)),
|
|
3949
|
+
/* @__PURE__ */ jsxs8("div", { class: `${p10}-form-actions`, children: [
|
|
3950
|
+
skipLabel && onSkip ? /* @__PURE__ */ jsx10("button", { type: "button", class: `${p10}-form-skip`, onClick: onSkip, disabled, "data-testid": skipTestId, children: skipLabel }) : null,
|
|
3951
|
+
/* @__PURE__ */ jsx10("button", { type: "submit", class: `${p10}-form-submit`, disabled, "data-testid": submitTestId, children: submitLabel })
|
|
3952
|
+
] })
|
|
3953
|
+
] });
|
|
3954
|
+
}
|
|
3955
|
+
function Field({
|
|
3956
|
+
field,
|
|
3957
|
+
value,
|
|
3958
|
+
otherText,
|
|
3959
|
+
error,
|
|
3960
|
+
disabled,
|
|
3961
|
+
strings,
|
|
3962
|
+
onChange,
|
|
3963
|
+
onOtherChange
|
|
3964
|
+
}) {
|
|
3965
|
+
const fieldTid = tid(TID.formField, field.name);
|
|
3966
|
+
const control = renderControl({ field, value, otherText, disabled, strings, onChange, onOtherChange, fieldTid });
|
|
3967
|
+
return /* @__PURE__ */ jsxs8("label", { class: `${p10}-field`, "data-field": field.name, "data-invalid": error ? "true" : void 0, children: [
|
|
3968
|
+
/* @__PURE__ */ jsxs8("span", { class: `${p10}-field-label`, children: [
|
|
3969
|
+
field.label,
|
|
3970
|
+
field.required ?? true ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-req`, "aria-hidden": "true", children: " *" }) : null
|
|
3971
|
+
] }),
|
|
3972
|
+
control,
|
|
3973
|
+
field.validationHint && !error ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-hint`, children: field.validationHint }) : null,
|
|
3974
|
+
error ? /* @__PURE__ */ jsx10("span", { class: `${p10}-field-error`, role: "alert", children: error }) : null
|
|
3975
|
+
] });
|
|
3976
|
+
}
|
|
3977
|
+
function renderControl(args) {
|
|
3978
|
+
const { field, value, otherText, disabled, strings, onChange, onOtherChange, fieldTid } = args;
|
|
3979
|
+
const str2 = typeof value === "string" ? value : "";
|
|
3980
|
+
switch (field.type) {
|
|
3981
|
+
case "textarea":
|
|
3982
|
+
return /* @__PURE__ */ jsx10(
|
|
3983
|
+
"textarea",
|
|
3984
|
+
{
|
|
3985
|
+
class: `${p10}-field-input`,
|
|
3986
|
+
rows: 3,
|
|
3987
|
+
value: str2,
|
|
3988
|
+
placeholder: field.placeholder,
|
|
3989
|
+
disabled,
|
|
3990
|
+
onInput: (e) => onChange(e.target.value),
|
|
3991
|
+
"data-testid": fieldTid
|
|
3992
|
+
}
|
|
3993
|
+
);
|
|
3994
|
+
case "select":
|
|
3995
|
+
return /* @__PURE__ */ jsxs8(
|
|
3996
|
+
"select",
|
|
3997
|
+
{
|
|
3998
|
+
class: `${p10}-field-input`,
|
|
3999
|
+
value: str2,
|
|
4000
|
+
disabled,
|
|
4001
|
+
onChange: (e) => onChange(e.target.value),
|
|
4002
|
+
"data-testid": fieldTid,
|
|
4003
|
+
children: [
|
|
4004
|
+
/* @__PURE__ */ jsx10("option", { value: "", children: field.placeholder ?? "\u2014" }),
|
|
4005
|
+
(field.options ?? []).map((o) => /* @__PURE__ */ jsx10("option", { value: o.value, children: o.label ?? o.value }, o.value))
|
|
4006
|
+
]
|
|
4007
|
+
}
|
|
4008
|
+
);
|
|
4009
|
+
case "radio": {
|
|
4010
|
+
const isOther = field.allowOther && str2 === OTHER;
|
|
4011
|
+
return /* @__PURE__ */ jsxs8("div", { class: `${p10}-field-choices`, role: "radiogroup", "data-testid": fieldTid, children: [
|
|
4012
|
+
(field.options ?? []).map((o) => /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
|
|
4013
|
+
/* @__PURE__ */ jsx10(
|
|
4014
|
+
"input",
|
|
4015
|
+
{
|
|
4016
|
+
type: "radio",
|
|
4017
|
+
name: `${p10}-${field.name}`,
|
|
4018
|
+
checked: str2 === o.value,
|
|
4019
|
+
disabled,
|
|
4020
|
+
onChange: () => onChange(o.value)
|
|
4021
|
+
}
|
|
4022
|
+
),
|
|
4023
|
+
/* @__PURE__ */ jsx10("span", { children: o.label ?? o.value })
|
|
4024
|
+
] }, o.value)),
|
|
4025
|
+
field.allowOther ? /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
|
|
4026
|
+
/* @__PURE__ */ jsx10(
|
|
4027
|
+
"input",
|
|
4028
|
+
{
|
|
4029
|
+
type: "radio",
|
|
4030
|
+
name: `${p10}-${field.name}`,
|
|
4031
|
+
checked: str2 === OTHER,
|
|
4032
|
+
disabled,
|
|
4033
|
+
onChange: () => onChange(OTHER)
|
|
4034
|
+
}
|
|
4035
|
+
),
|
|
4036
|
+
/* @__PURE__ */ jsx10("span", { children: strings.formOther })
|
|
4037
|
+
] }) : null,
|
|
4038
|
+
isOther ? /* @__PURE__ */ jsx10(
|
|
4039
|
+
"input",
|
|
4040
|
+
{
|
|
4041
|
+
class: `${p10}-field-input`,
|
|
4042
|
+
value: otherText,
|
|
4043
|
+
placeholder: field.placeholder ?? strings.formOtherPlaceholder,
|
|
4044
|
+
disabled,
|
|
4045
|
+
onInput: (e) => onOtherChange(e.target.value)
|
|
4046
|
+
}
|
|
4047
|
+
) : null
|
|
4048
|
+
] });
|
|
4049
|
+
}
|
|
4050
|
+
case "checkbox":
|
|
4051
|
+
return /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
|
|
4052
|
+
/* @__PURE__ */ jsx10(
|
|
4053
|
+
"input",
|
|
4054
|
+
{
|
|
4055
|
+
type: "checkbox",
|
|
4056
|
+
checked: str2 === "true",
|
|
4057
|
+
disabled,
|
|
4058
|
+
onChange: (e) => onChange(e.target.checked ? "true" : ""),
|
|
4059
|
+
"data-testid": fieldTid
|
|
4060
|
+
}
|
|
4061
|
+
),
|
|
4062
|
+
/* @__PURE__ */ jsx10("span", { children: field.placeholder ?? field.label })
|
|
4063
|
+
] });
|
|
4064
|
+
case "multiselect": {
|
|
4065
|
+
const selected = Array.isArray(value) ? value : [];
|
|
4066
|
+
const toggle = (v, on) => onChange(on ? [...selected, v] : selected.filter((x) => x !== v));
|
|
4067
|
+
return /* @__PURE__ */ jsxs8("div", { class: `${p10}-field-choices`, "data-testid": fieldTid, children: [
|
|
4068
|
+
(field.options ?? []).map((o) => /* @__PURE__ */ jsxs8("label", { class: `${p10}-choice`, children: [
|
|
4069
|
+
/* @__PURE__ */ jsx10(
|
|
4070
|
+
"input",
|
|
4071
|
+
{
|
|
4072
|
+
type: "checkbox",
|
|
4073
|
+
checked: selected.includes(o.value),
|
|
4074
|
+
disabled,
|
|
4075
|
+
onChange: (e) => toggle(o.value, e.target.checked)
|
|
4076
|
+
}
|
|
4077
|
+
),
|
|
4078
|
+
/* @__PURE__ */ jsx10("span", { children: o.label ?? o.value })
|
|
4079
|
+
] }, o.value)),
|
|
4080
|
+
field.allowOther || (field.options ?? []).length === 0 ? /* @__PURE__ */ jsx10(
|
|
4081
|
+
"textarea",
|
|
4082
|
+
{
|
|
4083
|
+
class: `${p10}-field-input`,
|
|
4084
|
+
rows: 2,
|
|
4085
|
+
value: otherText,
|
|
4086
|
+
placeholder: field.placeholder ?? strings.formOtherPlaceholder,
|
|
4087
|
+
disabled,
|
|
4088
|
+
onInput: (e) => onOtherChange(e.target.value)
|
|
4089
|
+
}
|
|
4090
|
+
) : null
|
|
4091
|
+
] });
|
|
4092
|
+
}
|
|
4093
|
+
default:
|
|
4094
|
+
return /* @__PURE__ */ jsx10(
|
|
4095
|
+
"input",
|
|
4096
|
+
{
|
|
4097
|
+
class: `${p10}-field-input`,
|
|
4098
|
+
type: inputType(field.type),
|
|
4099
|
+
value: str2,
|
|
4100
|
+
placeholder: field.placeholder,
|
|
4101
|
+
disabled,
|
|
4102
|
+
onInput: (e) => onChange(e.target.value),
|
|
4103
|
+
"data-testid": fieldTid
|
|
4104
|
+
}
|
|
4105
|
+
);
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
function inputType(type) {
|
|
4109
|
+
return type === "number" || type === "email" || type === "tel" || type === "url" ? type : "text";
|
|
4110
|
+
}
|
|
4111
|
+
function seedValues(fields) {
|
|
4112
|
+
const out = {};
|
|
4113
|
+
for (const f of fields) {
|
|
4114
|
+
if (f.defaultValue == null) continue;
|
|
4115
|
+
out[f.name] = f.type === "multiselect" ? f.defaultValue.split(",").map((s) => s.trim()).filter(Boolean) : f.defaultValue;
|
|
4116
|
+
}
|
|
4117
|
+
return out;
|
|
4118
|
+
}
|
|
4119
|
+
function resolveValues(fields, values, other) {
|
|
4120
|
+
const out = { ...values };
|
|
4121
|
+
for (const f of fields) {
|
|
4122
|
+
const otherText = other[f.name]?.trim();
|
|
4123
|
+
if (f.type === "radio" && f.allowOther && values[f.name] === OTHER) {
|
|
4124
|
+
out[f.name] = otherText ?? "";
|
|
4125
|
+
} else if (f.type === "multiselect" && otherText) {
|
|
4126
|
+
const tokens = otherText.split(/[,\n;]+/).map((t) => t.trim()).filter(Boolean);
|
|
4127
|
+
const base = Array.isArray(values[f.name]) ? values[f.name] : [];
|
|
4128
|
+
out[f.name] = [...base, ...tokens];
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
return out;
|
|
4132
|
+
}
|
|
4133
|
+
|
|
4134
|
+
// src/ui/intake-gate.tsx
|
|
4135
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
4136
|
+
var p11 = BRAND.cssPrefix;
|
|
4137
|
+
function IntakeGate({ intake, strings, onComplete }) {
|
|
4138
|
+
return /* @__PURE__ */ jsxs9("div", { class: `${p11}-intake`, "data-testid": TID.intakeForm, children: [
|
|
4139
|
+
intake.title ? /* @__PURE__ */ jsx11("h3", { class: `${p11}-intake-title`, children: intake.title }) : null,
|
|
4140
|
+
intake.description ? /* @__PURE__ */ jsx11("p", { class: `${p11}-intake-desc`, children: intake.description }) : null,
|
|
4141
|
+
/* @__PURE__ */ jsx11(
|
|
4142
|
+
DynamicForm,
|
|
4143
|
+
{
|
|
4144
|
+
fields: intake.fields,
|
|
4145
|
+
strings,
|
|
4146
|
+
submitLabel: intake.submitLabel ?? strings.intakeSubmit,
|
|
4147
|
+
onSubmit: onComplete,
|
|
4148
|
+
skipLabel: intake.skippable ? strings.intakeSkip : void 0,
|
|
4149
|
+
onSkip: intake.skippable ? () => onComplete({}) : void 0,
|
|
4150
|
+
submitTestId: TID.intakeSubmit,
|
|
4151
|
+
skipTestId: TID.intakeSkip
|
|
4152
|
+
}
|
|
4153
|
+
)
|
|
4154
|
+
] });
|
|
4155
|
+
}
|
|
4156
|
+
|
|
3536
4157
|
// src/ui/message-list.tsx
|
|
3537
|
-
import { useEffect as useEffect8, useLayoutEffect, useRef as useRef5, useState as
|
|
3538
|
-
import { useComputed as
|
|
4158
|
+
import { useEffect as useEffect8, useLayoutEffect, useRef as useRef5, useState as useState6 } from "preact/hooks";
|
|
4159
|
+
import { useComputed as useComputed5 } from "@preact/signals";
|
|
3539
4160
|
|
|
3540
4161
|
// src/ui/message-bubble.tsx
|
|
3541
|
-
import { useComputed as
|
|
4162
|
+
import { useComputed as useComputed4 } from "@preact/signals";
|
|
3542
4163
|
|
|
3543
4164
|
// src/ui/markdown.tsx
|
|
3544
4165
|
import { useEffect as useEffect7, useMemo, useRef as useRef4 } from "preact/hooks";
|
|
3545
4166
|
import { effect, signal as signal4 } from "@preact/signals";
|
|
3546
4167
|
import * as smd from "streaming-markdown";
|
|
3547
|
-
import { jsx as
|
|
4168
|
+
import { jsx as jsx12 } from "preact/jsx-runtime";
|
|
3548
4169
|
function MarkdownView({ textSig, doneSig }) {
|
|
3549
4170
|
const ref = useRef4(null);
|
|
3550
4171
|
useEffect7(() => {
|
|
@@ -3594,12 +4215,12 @@ function MarkdownView({ textSig, doneSig }) {
|
|
|
3594
4215
|
el.removeEventListener("click", onClick);
|
|
3595
4216
|
};
|
|
3596
4217
|
}, [textSig, doneSig]);
|
|
3597
|
-
return /* @__PURE__ */
|
|
4218
|
+
return /* @__PURE__ */ jsx12("div", { ref });
|
|
3598
4219
|
}
|
|
3599
4220
|
function StaticMarkdown({ text }) {
|
|
3600
4221
|
const textSig = useMemo(() => signal4(text), [text]);
|
|
3601
4222
|
const doneSig = useMemo(() => signal4(true), []);
|
|
3602
|
-
return /* @__PURE__ */
|
|
4223
|
+
return /* @__PURE__ */ jsx12(MarkdownView, { textSig, doneSig });
|
|
3603
4224
|
}
|
|
3604
4225
|
function hardenLink(a) {
|
|
3605
4226
|
const href = a.getAttribute("href") ?? "";
|
|
@@ -3611,29 +4232,248 @@ function hardenLink(a) {
|
|
|
3611
4232
|
a.rel = [...tokens].join(" ");
|
|
3612
4233
|
}
|
|
3613
4234
|
|
|
4235
|
+
// src/ui/tool-approval.tsx
|
|
4236
|
+
import { useComputed as useComputed2, useSignal } from "@preact/signals";
|
|
4237
|
+
import { Fragment, jsx as jsx13, jsxs as jsxs10 } from "preact/jsx-runtime";
|
|
4238
|
+
var p12 = BRAND.cssPrefix;
|
|
4239
|
+
function ToolApproval({ part, strings, active, onDecision }) {
|
|
4240
|
+
const approval = useComputed2(() => part.approvalSig.value);
|
|
4241
|
+
const input = useComputed2(() => part.inputSig.value);
|
|
4242
|
+
const reason = useSignal("");
|
|
4243
|
+
const decided = approval.value?.approved !== void 0;
|
|
4244
|
+
if (decided) {
|
|
4245
|
+
const ap = approval.value;
|
|
4246
|
+
return /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-approval ${p12}-tool-decided`, "data-testid": TID.toolDecision, children: [
|
|
4247
|
+
/* @__PURE__ */ jsx13("span", { class: `${p12}-tool-decided-label`, "data-approved": ap?.approved ? "true" : "false", children: ap?.approved ? strings.approved : strings.rejected }),
|
|
4248
|
+
/* @__PURE__ */ jsx13("strong", { class: `${p12}-tool-title`, children: part.toolName }),
|
|
4249
|
+
ap?.reason ? /* @__PURE__ */ jsx13("span", { class: `${p12}-tool-decided-value`, children: ap.reason }) : null
|
|
4250
|
+
] });
|
|
4251
|
+
}
|
|
4252
|
+
const args = summarizeInput(input.value);
|
|
4253
|
+
return /* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-approval`, "data-testid": TID.toolApproval, children: [
|
|
4254
|
+
/* @__PURE__ */ jsxs10("div", { class: `${p12}-tool-head`, children: [
|
|
4255
|
+
/* @__PURE__ */ jsx13("span", { class: `${p12}-tool-badge`, children: strings.approvalRequired }),
|
|
4256
|
+
/* @__PURE__ */ jsx13("strong", { class: `${p12}-tool-title`, children: part.toolName })
|
|
4257
|
+
] }),
|
|
4258
|
+
args ? /* @__PURE__ */ jsx13("pre", { class: `${p12}-tool-args`, children: args }) : null,
|
|
4259
|
+
active ? /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
4260
|
+
/* @__PURE__ */ jsx13(
|
|
4261
|
+
"input",
|
|
4262
|
+
{
|
|
4263
|
+
class: `${p12}-field-input`,
|
|
4264
|
+
value: reason.value,
|
|
4265
|
+
placeholder: strings.approvalReason,
|
|
4266
|
+
onInput: (e) => {
|
|
4267
|
+
reason.value = e.target.value;
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
),
|
|
4271
|
+
/* @__PURE__ */ jsxs10("div", { class: `${p12}-form-actions`, children: [
|
|
4272
|
+
/* @__PURE__ */ jsx13(
|
|
4273
|
+
"button",
|
|
4274
|
+
{
|
|
4275
|
+
type: "button",
|
|
4276
|
+
class: `${p12}-tool-reject`,
|
|
4277
|
+
onClick: () => onDecision(part.toolCallId, false, reason.value.trim() || void 0),
|
|
4278
|
+
"data-testid": TID.toolReject,
|
|
4279
|
+
children: strings.reject
|
|
4280
|
+
}
|
|
4281
|
+
),
|
|
4282
|
+
/* @__PURE__ */ jsx13(
|
|
4283
|
+
"button",
|
|
4284
|
+
{
|
|
4285
|
+
type: "button",
|
|
4286
|
+
class: `${p12}-tool-approve`,
|
|
4287
|
+
onClick: () => onDecision(part.toolCallId, true, reason.value.trim() || void 0),
|
|
4288
|
+
"data-testid": TID.toolApprove,
|
|
4289
|
+
children: strings.approve
|
|
4290
|
+
}
|
|
4291
|
+
)
|
|
4292
|
+
] })
|
|
4293
|
+
] }) : /* @__PURE__ */ jsx13("p", { class: `${p12}-tool-stale-note`, children: strings.stepNoLongerActive })
|
|
4294
|
+
] });
|
|
4295
|
+
}
|
|
4296
|
+
function summarizeInput(input) {
|
|
4297
|
+
if (input == null) return "";
|
|
4298
|
+
try {
|
|
4299
|
+
const json = typeof input === "string" ? input : JSON.stringify(input, null, 2);
|
|
4300
|
+
return json.length > 600 ? `${json.slice(0, 600)}\u2026` : json;
|
|
4301
|
+
} catch {
|
|
4302
|
+
return "";
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
|
|
4306
|
+
// src/ui/tool-ask-input.tsx
|
|
4307
|
+
import { useComputed as useComputed3 } from "@preact/signals";
|
|
4308
|
+
|
|
4309
|
+
// src/ui/form/field.ts
|
|
4310
|
+
function parseAskUserInput(input) {
|
|
4311
|
+
const raw = input && typeof input === "object" ? input : {};
|
|
4312
|
+
const responseType = raw.responseType;
|
|
4313
|
+
return {
|
|
4314
|
+
title: str(raw.title),
|
|
4315
|
+
question: str(raw.question) ?? "Please provide the missing information.",
|
|
4316
|
+
description: str(raw.description),
|
|
4317
|
+
placeholder: str(raw.placeholder),
|
|
4318
|
+
responseType: responseType === "single-choice" || responseType === "multi-choice" || responseType === "confirmation" || responseType === "free-text" ? responseType : "free-text",
|
|
4319
|
+
choices: Array.isArray(raw.choices) ? raw.choices : void 0,
|
|
4320
|
+
allowOther: typeof raw.allowOther === "boolean" ? raw.allowOther : void 0,
|
|
4321
|
+
required: typeof raw.required === "boolean" ? raw.required : true,
|
|
4322
|
+
defaultValues: Array.isArray(raw.defaultValues) ? raw.defaultValues.filter((v) => typeof v === "string") : void 0,
|
|
4323
|
+
minSelections: num(raw.minSelections),
|
|
4324
|
+
maxSelections: num(raw.maxSelections),
|
|
4325
|
+
validationHint: str(raw.validationHint)
|
|
4326
|
+
};
|
|
4327
|
+
}
|
|
4328
|
+
function askInputToFields(req) {
|
|
4329
|
+
if (req.responseType === "confirmation") return [];
|
|
4330
|
+
const options = (req.choices ?? []).map(normalizeChoice).filter((c) => c !== null);
|
|
4331
|
+
let type = "textarea";
|
|
4332
|
+
if (req.responseType === "single-choice" && options.length > 0) type = "radio";
|
|
4333
|
+
else if (req.responseType === "multi-choice") type = "multiselect";
|
|
4334
|
+
const defaultValue = type === "multiselect" ? req.defaultValues?.join(", ") : req.defaultValues?.[0];
|
|
4335
|
+
return [
|
|
4336
|
+
{
|
|
4337
|
+
name: "answer",
|
|
4338
|
+
label: req.question,
|
|
4339
|
+
type,
|
|
4340
|
+
placeholder: req.placeholder,
|
|
4341
|
+
required: req.required ?? true,
|
|
4342
|
+
defaultValue,
|
|
4343
|
+
options: options.length > 0 ? options : void 0,
|
|
4344
|
+
allowOther: req.allowOther,
|
|
4345
|
+
validationHint: req.validationHint,
|
|
4346
|
+
validation: type === "multiselect" ? { minSelections: req.minSelections, maxSelections: req.maxSelections } : void 0
|
|
4347
|
+
}
|
|
4348
|
+
];
|
|
4349
|
+
}
|
|
4350
|
+
function normalizeChoice(c) {
|
|
4351
|
+
if (typeof c === "string") return c ? { value: c, label: c } : null;
|
|
4352
|
+
if (c && typeof c.value === "string" && c.value)
|
|
4353
|
+
return { value: c.value, label: c.label ?? c.value, description: c.description };
|
|
4354
|
+
return null;
|
|
4355
|
+
}
|
|
4356
|
+
function str(v) {
|
|
4357
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
4358
|
+
}
|
|
4359
|
+
function num(v) {
|
|
4360
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
4361
|
+
}
|
|
4362
|
+
|
|
4363
|
+
// src/ui/tool-ask-input.tsx
|
|
4364
|
+
import { jsx as jsx14, jsxs as jsxs11 } from "preact/jsx-runtime";
|
|
4365
|
+
var p13 = BRAND.cssPrefix;
|
|
4366
|
+
function ToolAskInput({ part, strings, active, onSubmit }) {
|
|
4367
|
+
const state = useComputed3(() => part.stateSig.value);
|
|
4368
|
+
const request = useComputed3(() => parseAskUserInput(part.inputSig.value));
|
|
4369
|
+
const decided = state.value === "output" || state.value === "error";
|
|
4370
|
+
if (decided) {
|
|
4371
|
+
return /* @__PURE__ */ jsx14(DecidedSummary, { part, strings });
|
|
4372
|
+
}
|
|
4373
|
+
if (!active) {
|
|
4374
|
+
return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input ${p13}-tool-stale`, "data-testid": TID.toolAskInput, children: [
|
|
4375
|
+
/* @__PURE__ */ jsx14(Header, { strings, title: request.value.title ?? request.value.question }),
|
|
4376
|
+
/* @__PURE__ */ jsx14("p", { class: `${p13}-tool-stale-note`, children: strings.stepNoLongerActive })
|
|
4377
|
+
] });
|
|
4378
|
+
}
|
|
4379
|
+
const req = request.value;
|
|
4380
|
+
const isConfirmation = req.responseType === "confirmation";
|
|
4381
|
+
return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input`, "data-testid": TID.toolAskInput, children: [
|
|
4382
|
+
/* @__PURE__ */ jsx14(Header, { strings, title: req.title }),
|
|
4383
|
+
req.description ? /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-desc`, children: req.description }) : null,
|
|
4384
|
+
isConfirmation ? /* @__PURE__ */ jsx14("p", { class: `${p13}-tool-question`, children: req.question }) : null,
|
|
4385
|
+
isConfirmation ? /* @__PURE__ */ jsxs11("div", { class: `${p13}-form-actions`, children: [
|
|
4386
|
+
/* @__PURE__ */ jsx14(
|
|
4387
|
+
"button",
|
|
4388
|
+
{
|
|
4389
|
+
type: "button",
|
|
4390
|
+
class: `${p13}-form-skip`,
|
|
4391
|
+
onClick: () => onSubmit(part.toolCallId, { confirmed: false }),
|
|
4392
|
+
"data-testid": TID.toolInputSkip,
|
|
4393
|
+
children: strings.reject
|
|
4394
|
+
}
|
|
4395
|
+
),
|
|
4396
|
+
/* @__PURE__ */ jsx14(
|
|
4397
|
+
"button",
|
|
4398
|
+
{
|
|
4399
|
+
type: "button",
|
|
4400
|
+
class: `${p13}-form-submit`,
|
|
4401
|
+
onClick: () => onSubmit(part.toolCallId, { confirmed: true }),
|
|
4402
|
+
"data-testid": TID.toolInputSubmit,
|
|
4403
|
+
children: strings.approve
|
|
4404
|
+
}
|
|
4405
|
+
)
|
|
4406
|
+
] }) : /* @__PURE__ */ jsx14(
|
|
4407
|
+
DynamicForm,
|
|
4408
|
+
{
|
|
4409
|
+
fields: askInputToFields(req),
|
|
4410
|
+
strings,
|
|
4411
|
+
submitLabel: strings.inputSubmit,
|
|
4412
|
+
onSubmit: (values) => onSubmit(part.toolCallId, values),
|
|
4413
|
+
skipLabel: req.required === false ? strings.inputSkip : void 0,
|
|
4414
|
+
onSkip: req.required === false ? () => onSubmit(part.toolCallId, {}) : void 0,
|
|
4415
|
+
submitTestId: TID.toolInputSubmit,
|
|
4416
|
+
skipTestId: TID.toolInputSkip
|
|
4417
|
+
}
|
|
4418
|
+
)
|
|
4419
|
+
] });
|
|
4420
|
+
}
|
|
4421
|
+
function Header({ strings, title }) {
|
|
4422
|
+
return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-head`, children: [
|
|
4423
|
+
/* @__PURE__ */ jsx14("span", { class: `${p13}-tool-badge`, children: strings.inputRequired }),
|
|
4424
|
+
title ? /* @__PURE__ */ jsx14("strong", { class: `${p13}-tool-title`, children: title }) : null
|
|
4425
|
+
] });
|
|
4426
|
+
}
|
|
4427
|
+
function DecidedSummary({ part, strings }) {
|
|
4428
|
+
const output = useComputed3(() => part.outputSig.value);
|
|
4429
|
+
const text = summarizeOutput(output.value) || strings.inputSubmitted;
|
|
4430
|
+
return /* @__PURE__ */ jsxs11("div", { class: `${p13}-tool-ask-input ${p13}-tool-decided`, "data-testid": TID.toolDecision, children: [
|
|
4431
|
+
/* @__PURE__ */ jsx14("span", { class: `${p13}-tool-decided-label`, children: strings.inputSubmitted }),
|
|
4432
|
+
/* @__PURE__ */ jsx14("span", { class: `${p13}-tool-decided-value`, children: text })
|
|
4433
|
+
] });
|
|
4434
|
+
}
|
|
4435
|
+
function summarizeOutput(output) {
|
|
4436
|
+
if (output == null) return "";
|
|
4437
|
+
if (typeof output === "string") return output;
|
|
4438
|
+
if (typeof output === "object") {
|
|
4439
|
+
const rec = output;
|
|
4440
|
+
if ("confirmed" in rec) return rec.confirmed ? "Yes" : "No";
|
|
4441
|
+
return Object.values(rec).filter((v) => typeof v === "string" || typeof v === "number").join(", ");
|
|
4442
|
+
}
|
|
4443
|
+
return String(output);
|
|
4444
|
+
}
|
|
4445
|
+
|
|
3614
4446
|
// src/ui/tool-chip.tsx
|
|
3615
|
-
import { jsx as
|
|
4447
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "preact/jsx-runtime";
|
|
3616
4448
|
function ToolChip({ part, strings }) {
|
|
3617
|
-
const
|
|
3618
|
-
return /* @__PURE__ */
|
|
3619
|
-
/* @__PURE__ */
|
|
4449
|
+
const p33 = BRAND.cssPrefix;
|
|
4450
|
+
return /* @__PURE__ */ jsxs12("span", { class: `${p33}-tool-chip`, role: "status", children: [
|
|
4451
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
3620
4452
|
strings.usedTool,
|
|
3621
4453
|
":"
|
|
3622
4454
|
] }),
|
|
3623
|
-
/* @__PURE__ */
|
|
4455
|
+
/* @__PURE__ */ jsx15("strong", { children: part.toolName })
|
|
3624
4456
|
] });
|
|
3625
4457
|
}
|
|
3626
4458
|
|
|
3627
4459
|
// src/ui/message-bubble.tsx
|
|
3628
|
-
import { jsx as
|
|
3629
|
-
var
|
|
3630
|
-
function MessageBubble({
|
|
3631
|
-
|
|
4460
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "preact/jsx-runtime";
|
|
4461
|
+
var p14 = BRAND.cssPrefix;
|
|
4462
|
+
function MessageBubble({
|
|
4463
|
+
message,
|
|
4464
|
+
strings,
|
|
4465
|
+
responseMode,
|
|
4466
|
+
showReasoning,
|
|
4467
|
+
showToolCalls,
|
|
4468
|
+
interactive = false,
|
|
4469
|
+
tool
|
|
4470
|
+
}) {
|
|
4471
|
+
const parts = useComputed4(() => message.partsSig.value);
|
|
3632
4472
|
const partList = parts.value;
|
|
3633
|
-
const hasAnswerText =
|
|
4473
|
+
const hasAnswerText = useComputed4(
|
|
3634
4474
|
() => message.partsSig.value.some((part) => part.kind === "text" && part.textSig.value.length > 0)
|
|
3635
4475
|
);
|
|
3636
|
-
const reasoningVisible =
|
|
4476
|
+
const reasoningVisible = useComputed4(
|
|
3637
4477
|
() => showReasoning && message.partsSig.value.some((part) => part.kind === "reasoning")
|
|
3638
4478
|
);
|
|
3639
4479
|
const streaming = message.role === "assistant" && message.status === "streaming";
|
|
@@ -3641,23 +4481,25 @@ function MessageBubble({ message, strings, responseMode, showReasoning, showTool
|
|
|
3641
4481
|
const working = streaming && !hasAnswerText.value;
|
|
3642
4482
|
const showStreamDots = streaming && !bufferedHold && !(reasoningVisible.value && working);
|
|
3643
4483
|
const stamp = formatStamp(message.createdAt);
|
|
3644
|
-
return /* @__PURE__ */
|
|
3645
|
-
/* @__PURE__ */
|
|
3646
|
-
bufferedHold ? /* @__PURE__ */
|
|
4484
|
+
return /* @__PURE__ */ jsx16("div", { class: `${p14}-bubble-row`, "data-role": message.role, "data-testid": tid(TID.messageBubble, message.id), children: /* @__PURE__ */ jsxs13("div", { class: `${p14}-bubble-col`, children: [
|
|
4485
|
+
/* @__PURE__ */ jsxs13("div", { class: `${p14}-bubble`, children: [
|
|
4486
|
+
bufferedHold ? /* @__PURE__ */ jsx16(LoadingSpinner, { label: strings.loading }) : partList.map((part) => /* @__PURE__ */ jsx16(
|
|
3647
4487
|
PartView,
|
|
3648
4488
|
{
|
|
3649
4489
|
part,
|
|
3650
4490
|
active: working,
|
|
3651
4491
|
strings,
|
|
3652
4492
|
showReasoning,
|
|
3653
|
-
showToolCalls
|
|
4493
|
+
showToolCalls,
|
|
4494
|
+
interactive,
|
|
4495
|
+
tool
|
|
3654
4496
|
},
|
|
3655
4497
|
partKey(part)
|
|
3656
4498
|
)),
|
|
3657
|
-
showStreamDots && /* @__PURE__ */
|
|
3658
|
-
message.status === "error" && message.errorText ? /* @__PURE__ */
|
|
4499
|
+
showStreamDots && /* @__PURE__ */ jsx16(TypingDots, {}),
|
|
4500
|
+
message.status === "error" && message.errorText ? /* @__PURE__ */ jsx16("div", { class: `${p14}-error`, role: "alert", children: /* @__PURE__ */ jsx16("span", { children: message.errorText }) }) : null
|
|
3659
4501
|
] }),
|
|
3660
|
-
stamp ? /* @__PURE__ */
|
|
4502
|
+
stamp ? /* @__PURE__ */ jsx16("time", { class: `${p14}-bubble-time`, dateTime: stamp.iso, title: stamp.full, children: stamp.short }) : null
|
|
3661
4503
|
] }) });
|
|
3662
4504
|
}
|
|
3663
4505
|
function formatStamp(createdAt) {
|
|
@@ -3678,32 +4520,62 @@ function PartView({
|
|
|
3678
4520
|
active,
|
|
3679
4521
|
strings,
|
|
3680
4522
|
showReasoning,
|
|
3681
|
-
showToolCalls
|
|
4523
|
+
showToolCalls,
|
|
4524
|
+
interactive,
|
|
4525
|
+
tool
|
|
3682
4526
|
}) {
|
|
3683
4527
|
switch (part.kind) {
|
|
3684
4528
|
case "text":
|
|
3685
|
-
return /* @__PURE__ */
|
|
4529
|
+
return /* @__PURE__ */ jsx16(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
|
|
3686
4530
|
case "reasoning":
|
|
3687
|
-
return showReasoning ? /* @__PURE__ */
|
|
4531
|
+
return showReasoning ? /* @__PURE__ */ jsx16(ReasoningView, { part, active, strings }) : null;
|
|
3688
4532
|
case "tool":
|
|
3689
|
-
return
|
|
4533
|
+
return /* @__PURE__ */ jsx16(
|
|
4534
|
+
ToolPartView,
|
|
4535
|
+
{
|
|
4536
|
+
part,
|
|
4537
|
+
strings,
|
|
4538
|
+
showToolCalls,
|
|
4539
|
+
interactive,
|
|
4540
|
+
tool
|
|
4541
|
+
}
|
|
4542
|
+
);
|
|
3690
4543
|
case "file":
|
|
3691
4544
|
if (part.mediaType.startsWith("image/")) {
|
|
3692
|
-
return /* @__PURE__ */
|
|
4545
|
+
return /* @__PURE__ */ jsx16("img", { src: part.url, alt: "", loading: "lazy" });
|
|
3693
4546
|
}
|
|
3694
|
-
return /* @__PURE__ */
|
|
4547
|
+
return /* @__PURE__ */ jsx16("a", { href: part.url, target: "_blank", rel: "noreferrer noopener", children: part.url });
|
|
3695
4548
|
case "source":
|
|
3696
4549
|
return null;
|
|
3697
4550
|
}
|
|
3698
4551
|
}
|
|
4552
|
+
function ToolPartView({
|
|
4553
|
+
part,
|
|
4554
|
+
strings,
|
|
4555
|
+
showToolCalls,
|
|
4556
|
+
interactive,
|
|
4557
|
+
tool
|
|
4558
|
+
}) {
|
|
4559
|
+
const state = useComputed4(() => part.stateSig.value);
|
|
4560
|
+
const hasApproval = useComputed4(() => part.approvalSig.value !== void 0);
|
|
4561
|
+
if (tool?.humanInLoop) {
|
|
4562
|
+
if (hasApproval.value || state.value === "awaiting-approval") {
|
|
4563
|
+
return /* @__PURE__ */ jsx16(ToolApproval, { part, strings, active: interactive, onDecision: tool.onDecision });
|
|
4564
|
+
}
|
|
4565
|
+
if (isAskUserInputTool(part.toolName) || state.value === "awaiting-input") {
|
|
4566
|
+
return /* @__PURE__ */ jsx16(ToolAskInput, { part, strings, active: interactive, onSubmit: tool.onResult });
|
|
4567
|
+
}
|
|
4568
|
+
}
|
|
4569
|
+
return showToolCalls ? /* @__PURE__ */ jsx16(ToolChip, { part, strings }) : null;
|
|
4570
|
+
}
|
|
3699
4571
|
function ReasoningView({
|
|
3700
4572
|
part,
|
|
3701
4573
|
active,
|
|
3702
4574
|
strings
|
|
3703
4575
|
}) {
|
|
3704
|
-
return /* @__PURE__ */
|
|
3705
|
-
/* @__PURE__ */
|
|
3706
|
-
/* @__PURE__ */
|
|
4576
|
+
return /* @__PURE__ */ jsxs13("details", { class: `${p14}-reasoning`, open: active, "data-active": active ? "true" : void 0, children: [
|
|
4577
|
+
/* @__PURE__ */ jsx16("summary", { class: `${p14}-reasoning-summary`, children: /* @__PURE__ */ jsx16("span", { class: `${p14}-reasoning-label`, children: active ? strings.thinking : strings.thoughts }) }),
|
|
4578
|
+
/* @__PURE__ */ jsx16("div", { class: `${p14}-reasoning-body`, children: /* @__PURE__ */ jsx16(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig }) })
|
|
3707
4579
|
] });
|
|
3708
4580
|
}
|
|
3709
4581
|
function partKey(part) {
|
|
@@ -3720,29 +4592,38 @@ function partKey(part) {
|
|
|
3720
4592
|
}
|
|
3721
4593
|
}
|
|
3722
4594
|
function TypingDots() {
|
|
3723
|
-
return /* @__PURE__ */
|
|
3724
|
-
/* @__PURE__ */
|
|
3725
|
-
/* @__PURE__ */
|
|
3726
|
-
/* @__PURE__ */
|
|
4595
|
+
return /* @__PURE__ */ jsxs13("span", { class: `${p14}-typing`, "aria-hidden": "true", children: [
|
|
4596
|
+
/* @__PURE__ */ jsx16("span", {}),
|
|
4597
|
+
/* @__PURE__ */ jsx16("span", {}),
|
|
4598
|
+
/* @__PURE__ */ jsx16("span", {})
|
|
3727
4599
|
] });
|
|
3728
4600
|
}
|
|
3729
4601
|
function LoadingSpinner({ label }) {
|
|
3730
|
-
return /* @__PURE__ */
|
|
3731
|
-
/* @__PURE__ */
|
|
3732
|
-
/* @__PURE__ */
|
|
4602
|
+
return /* @__PURE__ */ jsxs13("span", { class: `${p14}-loading`, role: "status", children: [
|
|
4603
|
+
/* @__PURE__ */ jsx16("span", { class: `${p14}-loading-spinner`, "aria-hidden": "true" }),
|
|
4604
|
+
/* @__PURE__ */ jsx16("span", { class: `${p14}-loading-label`, children: label })
|
|
3733
4605
|
] });
|
|
3734
4606
|
}
|
|
3735
4607
|
|
|
3736
4608
|
// src/ui/message-list.tsx
|
|
3737
|
-
import { jsx as
|
|
3738
|
-
var
|
|
4609
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "preact/jsx-runtime";
|
|
4610
|
+
var p15 = BRAND.cssPrefix;
|
|
3739
4611
|
var STICK_THRESHOLD = 120;
|
|
3740
4612
|
var DIVIDER_IDLE_MS = 1200;
|
|
3741
|
-
function MessageList({
|
|
4613
|
+
function MessageList({
|
|
4614
|
+
messagesSig,
|
|
4615
|
+
strings,
|
|
4616
|
+
responseMode,
|
|
4617
|
+
showReasoning,
|
|
4618
|
+
showToolCalls,
|
|
4619
|
+
loading,
|
|
4620
|
+
idle,
|
|
4621
|
+
tool
|
|
4622
|
+
}) {
|
|
3742
4623
|
const ref = useRef5(null);
|
|
3743
|
-
const messages =
|
|
3744
|
-
const [showJump, setShowJump] =
|
|
3745
|
-
const [scrolling, setScrolling] =
|
|
4624
|
+
const messages = useComputed5(() => messagesSig.value);
|
|
4625
|
+
const [showJump, setShowJump] = useState6(false);
|
|
4626
|
+
const [scrolling, setScrolling] = useState6(false);
|
|
3746
4627
|
const hasHydratedRef = useRef5(false);
|
|
3747
4628
|
const firstMessageId = messages.value[0]?.id;
|
|
3748
4629
|
useLayoutEffect(() => {
|
|
@@ -3797,18 +4678,18 @@ function MessageList({ messagesSig, strings, responseMode, showReasoning, showTo
|
|
|
3797
4678
|
const el = ref.current;
|
|
3798
4679
|
if (!el) return;
|
|
3799
4680
|
const syncJump = () => setShowJump(el.scrollHeight - el.scrollTop - el.clientHeight > STICK_THRESHOLD * 2);
|
|
3800
|
-
let
|
|
4681
|
+
let idleTimer;
|
|
3801
4682
|
const onScroll = () => {
|
|
3802
4683
|
syncJump();
|
|
3803
4684
|
setScrolling(true);
|
|
3804
|
-
clearTimeout(
|
|
3805
|
-
|
|
4685
|
+
clearTimeout(idleTimer);
|
|
4686
|
+
idleTimer = setTimeout(() => setScrolling(false), DIVIDER_IDLE_MS);
|
|
3806
4687
|
};
|
|
3807
4688
|
el.addEventListener("scroll", onScroll, { passive: true });
|
|
3808
4689
|
syncJump();
|
|
3809
4690
|
return () => {
|
|
3810
4691
|
el.removeEventListener("scroll", onScroll);
|
|
3811
|
-
clearTimeout(
|
|
4692
|
+
clearTimeout(idleTimer);
|
|
3812
4693
|
};
|
|
3813
4694
|
}, []);
|
|
3814
4695
|
const jumpToBottom = () => {
|
|
@@ -3817,54 +4698,57 @@ function MessageList({ messagesSig, strings, responseMode, showReasoning, showTo
|
|
|
3817
4698
|
};
|
|
3818
4699
|
const rows = [];
|
|
3819
4700
|
let prevDay = "";
|
|
4701
|
+
const lastId = messages.value.at(-1)?.id;
|
|
3820
4702
|
for (const m of messages.value) {
|
|
3821
4703
|
const day = dayKey(m.createdAt);
|
|
3822
4704
|
if (day && day !== prevDay) {
|
|
3823
4705
|
rows.push(
|
|
3824
|
-
/* @__PURE__ */
|
|
4706
|
+
/* @__PURE__ */ jsx17("div", { class: `${p15}-date-divider`, children: /* @__PURE__ */ jsx17("span", { class: `${p15}-date-pill`, title: fullDate(m.createdAt), children: dayLabel(m.createdAt, strings) }) }, `day:${day}`)
|
|
3825
4707
|
);
|
|
3826
4708
|
prevDay = day;
|
|
3827
4709
|
}
|
|
3828
4710
|
rows.push(
|
|
3829
|
-
/* @__PURE__ */
|
|
4711
|
+
/* @__PURE__ */ jsx17(
|
|
3830
4712
|
MessageBubble,
|
|
3831
4713
|
{
|
|
3832
4714
|
message: m,
|
|
3833
4715
|
strings,
|
|
3834
4716
|
responseMode,
|
|
3835
4717
|
showReasoning,
|
|
3836
|
-
showToolCalls
|
|
4718
|
+
showToolCalls,
|
|
4719
|
+
interactive: Boolean(idle) && m.id === lastId,
|
|
4720
|
+
tool
|
|
3837
4721
|
},
|
|
3838
4722
|
m.id
|
|
3839
4723
|
)
|
|
3840
4724
|
);
|
|
3841
4725
|
}
|
|
3842
|
-
return /* @__PURE__ */
|
|
3843
|
-
/* @__PURE__ */
|
|
4726
|
+
return /* @__PURE__ */ jsxs14("div", { class: `${p15}-list-wrap`, children: [
|
|
4727
|
+
/* @__PURE__ */ jsxs14(
|
|
3844
4728
|
"div",
|
|
3845
4729
|
{
|
|
3846
4730
|
ref,
|
|
3847
|
-
class: `${
|
|
4731
|
+
class: `${p15}-list`,
|
|
3848
4732
|
role: "log",
|
|
3849
4733
|
"aria-live": "polite",
|
|
3850
4734
|
"aria-relevant": "additions text",
|
|
3851
4735
|
"data-scrolling": scrolling ? "true" : void 0,
|
|
3852
4736
|
children: [
|
|
3853
|
-
loading && messages.value.length === 0 ? /* @__PURE__ */
|
|
4737
|
+
loading && messages.value.length === 0 ? /* @__PURE__ */ jsx17("div", { class: `${p15}-list-loading`, role: "status", children: strings.messagesLoading }) : null,
|
|
3854
4738
|
rows
|
|
3855
4739
|
]
|
|
3856
4740
|
}
|
|
3857
4741
|
),
|
|
3858
|
-
showJump ? /* @__PURE__ */
|
|
4742
|
+
showJump ? /* @__PURE__ */ jsx17(
|
|
3859
4743
|
"button",
|
|
3860
4744
|
{
|
|
3861
4745
|
type: "button",
|
|
3862
|
-
class: `${
|
|
4746
|
+
class: `${p15}-jump`,
|
|
3863
4747
|
onClick: jumpToBottom,
|
|
3864
4748
|
"aria-label": strings.scrollToBottom,
|
|
3865
4749
|
title: strings.scrollToBottom,
|
|
3866
4750
|
"data-testid": TID.scrollToBottom,
|
|
3867
|
-
children: /* @__PURE__ */
|
|
4751
|
+
children: /* @__PURE__ */ jsx17(ChevronDownIcon, {})
|
|
3868
4752
|
}
|
|
3869
4753
|
) : null
|
|
3870
4754
|
] });
|
|
@@ -3893,7 +4777,7 @@ function dayLabel(createdAt, strings) {
|
|
|
3893
4777
|
}
|
|
3894
4778
|
|
|
3895
4779
|
// src/ui/conversation-list.tsx
|
|
3896
|
-
import { useEffect as useEffect9, useState as
|
|
4780
|
+
import { useEffect as useEffect9, useState as useState7 } from "preact/hooks";
|
|
3897
4781
|
|
|
3898
4782
|
// src/ui/history-groups.ts
|
|
3899
4783
|
var HISTORY_BUCKETS = ["today", "yesterday", "lastWeek", "older"];
|
|
@@ -3923,7 +4807,7 @@ function startOfDay(ms) {
|
|
|
3923
4807
|
}
|
|
3924
4808
|
|
|
3925
4809
|
// src/ui/conversation-list.tsx
|
|
3926
|
-
import { Fragment, jsx as
|
|
4810
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs15 } from "preact/jsx-runtime";
|
|
3927
4811
|
var log11 = logger.scope("history");
|
|
3928
4812
|
var BUCKET_TO_STRING = {
|
|
3929
4813
|
today: "dateToday",
|
|
@@ -3932,9 +4816,9 @@ var BUCKET_TO_STRING = {
|
|
|
3932
4816
|
older: "dateOlder"
|
|
3933
4817
|
};
|
|
3934
4818
|
function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }) {
|
|
3935
|
-
const
|
|
3936
|
-
const [state, setState] =
|
|
3937
|
-
const [sessions, setChats] =
|
|
4819
|
+
const p33 = BRAND.cssPrefix;
|
|
4820
|
+
const [state, setState] = useState7("loading");
|
|
4821
|
+
const [sessions, setChats] = useState7([]);
|
|
3938
4822
|
useEffect9(() => {
|
|
3939
4823
|
let cancelled = false;
|
|
3940
4824
|
transport.listSessions({ visitorId }).then((res) => {
|
|
@@ -3950,38 +4834,38 @@ function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }
|
|
|
3950
4834
|
cancelled = true;
|
|
3951
4835
|
};
|
|
3952
4836
|
}, [transport, visitorId]);
|
|
3953
|
-
const newChatButton = onNewChat ? /* @__PURE__ */
|
|
3954
|
-
/* @__PURE__ */
|
|
4837
|
+
const newChatButton = onNewChat ? /* @__PURE__ */ jsx18("div", { class: `${p33}-history-footer`, children: /* @__PURE__ */ jsxs15("button", { type: "button", class: `${p33}-history-new`, onClick: onNewChat, "data-testid": TID.sidebarNewChat, children: [
|
|
4838
|
+
/* @__PURE__ */ jsx18(PlusIcon, {}),
|
|
3955
4839
|
strings.historyNewChat
|
|
3956
4840
|
] }) }) : null;
|
|
3957
4841
|
if (state === "loading") {
|
|
3958
|
-
return /* @__PURE__ */
|
|
3959
|
-
/* @__PURE__ */
|
|
4842
|
+
return /* @__PURE__ */ jsxs15(Fragment2, { children: [
|
|
4843
|
+
/* @__PURE__ */ jsx18("div", { class: `${p33}-history-empty`, children: strings.historyLoading }),
|
|
3960
4844
|
newChatButton
|
|
3961
4845
|
] });
|
|
3962
4846
|
}
|
|
3963
4847
|
if (state === "error" || sessions.length === 0) {
|
|
3964
|
-
return /* @__PURE__ */
|
|
3965
|
-
/* @__PURE__ */
|
|
4848
|
+
return /* @__PURE__ */ jsxs15(Fragment2, { children: [
|
|
4849
|
+
/* @__PURE__ */ jsx18("div", { class: `${p33}-history-empty`, children: strings.historyEmpty }),
|
|
3966
4850
|
newChatButton
|
|
3967
4851
|
] });
|
|
3968
4852
|
}
|
|
3969
4853
|
const groups = groupByBucket(Date.now(), sessions);
|
|
3970
|
-
return /* @__PURE__ */
|
|
3971
|
-
/* @__PURE__ */
|
|
3972
|
-
/* @__PURE__ */
|
|
3973
|
-
group.sessions.map((chat) => /* @__PURE__ */
|
|
4854
|
+
return /* @__PURE__ */ jsxs15(Fragment2, { children: [
|
|
4855
|
+
/* @__PURE__ */ jsx18("div", { class: `${p33}-history`, role: "list", children: groups.map((group) => /* @__PURE__ */ jsxs15("div", { class: `${p33}-history-group`, children: [
|
|
4856
|
+
/* @__PURE__ */ jsx18("div", { class: `${p33}-history-heading`, children: strings[BUCKET_TO_STRING[group.bucket]] }),
|
|
4857
|
+
group.sessions.map((chat) => /* @__PURE__ */ jsxs15(
|
|
3974
4858
|
"button",
|
|
3975
4859
|
{
|
|
3976
4860
|
type: "button",
|
|
3977
4861
|
role: "listitem",
|
|
3978
|
-
class: `${
|
|
4862
|
+
class: `${p33}-history-item`,
|
|
3979
4863
|
onClick: () => onSelect(chat),
|
|
3980
4864
|
"data-closed": chat.canContinue ? void 0 : "true",
|
|
3981
4865
|
"data-testid": tid(TID.historyItem, chat.sessionId),
|
|
3982
4866
|
children: [
|
|
3983
|
-
/* @__PURE__ */
|
|
3984
|
-
chat.preview ? /* @__PURE__ */
|
|
4867
|
+
/* @__PURE__ */ jsx18("span", { class: `${p33}-history-title`, children: chat.title }),
|
|
4868
|
+
chat.preview ? /* @__PURE__ */ jsx18("span", { class: `${p33}-history-preview`, children: chat.preview }) : null
|
|
3985
4869
|
]
|
|
3986
4870
|
},
|
|
3987
4871
|
chat.sessionId
|
|
@@ -3992,21 +4876,21 @@ function ConversationList({ transport, strings, visitorId, onSelect, onNewChat }
|
|
|
3992
4876
|
}
|
|
3993
4877
|
|
|
3994
4878
|
// src/ui/chat-history-pane.tsx
|
|
3995
|
-
import { jsx as
|
|
4879
|
+
import { jsx as jsx19 } from "preact/jsx-runtime";
|
|
3996
4880
|
function ChatHistoryPane(props2) {
|
|
3997
|
-
return /* @__PURE__ */
|
|
4881
|
+
return /* @__PURE__ */ jsx19(ConversationList, { ...props2 });
|
|
3998
4882
|
}
|
|
3999
4883
|
|
|
4000
4884
|
// src/ui/suggestions.tsx
|
|
4001
|
-
import { jsx as
|
|
4002
|
-
var
|
|
4885
|
+
import { jsx as jsx20 } from "preact/jsx-runtime";
|
|
4886
|
+
var p16 = BRAND.cssPrefix;
|
|
4003
4887
|
function Suggestions({ suggestions, onPick }) {
|
|
4004
4888
|
if (suggestions.length === 0) return null;
|
|
4005
|
-
return /* @__PURE__ */
|
|
4889
|
+
return /* @__PURE__ */ jsx20("div", { class: `${p16}-suggestions`, role: "group", "aria-label": "Suggested replies", children: suggestions.map((s, i) => /* @__PURE__ */ jsx20(
|
|
4006
4890
|
"button",
|
|
4007
4891
|
{
|
|
4008
4892
|
type: "button",
|
|
4009
|
-
class: `${
|
|
4893
|
+
class: `${p16}-suggestion`,
|
|
4010
4894
|
onClick: () => onPick(s),
|
|
4011
4895
|
"data-testid": tid(TID.suggestion, i),
|
|
4012
4896
|
children: s.label
|
|
@@ -4016,8 +4900,8 @@ function Suggestions({ suggestions, onPick }) {
|
|
|
4016
4900
|
}
|
|
4017
4901
|
|
|
4018
4902
|
// src/ui/panel.tsx
|
|
4019
|
-
import { Fragment as
|
|
4020
|
-
var
|
|
4903
|
+
import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs16 } from "preact/jsx-runtime";
|
|
4904
|
+
var p17 = BRAND.cssPrefix;
|
|
4021
4905
|
function Panel(props2) {
|
|
4022
4906
|
const { options, onClose } = props2;
|
|
4023
4907
|
const s = options.strings;
|
|
@@ -4041,18 +4925,18 @@ function Panel(props2) {
|
|
|
4041
4925
|
}, []);
|
|
4042
4926
|
const { visible: dragOver } = useFileDrop({ containerRef, onDrop: onDropItems });
|
|
4043
4927
|
useDragMove(containerRef.current, options.mode === "modal");
|
|
4044
|
-
return /* @__PURE__ */
|
|
4928
|
+
return /* @__PURE__ */ jsxs16(
|
|
4045
4929
|
"div",
|
|
4046
4930
|
{
|
|
4047
4931
|
ref: containerRef,
|
|
4048
|
-
class: `${
|
|
4932
|
+
class: `${p17}-panel`,
|
|
4049
4933
|
role: "dialog",
|
|
4050
4934
|
"aria-modal": "false",
|
|
4051
4935
|
"aria-label": s.panelTitle,
|
|
4052
4936
|
style: { position: "relative" },
|
|
4053
4937
|
"data-testid": TID.panel,
|
|
4054
4938
|
children: [
|
|
4055
|
-
/* @__PURE__ */
|
|
4939
|
+
/* @__PURE__ */ jsx21(
|
|
4056
4940
|
PanelContent,
|
|
4057
4941
|
{
|
|
4058
4942
|
...props2,
|
|
@@ -4061,7 +4945,7 @@ function Panel(props2) {
|
|
|
4061
4945
|
composerAttachApiRef
|
|
4062
4946
|
}
|
|
4063
4947
|
),
|
|
4064
|
-
/* @__PURE__ */
|
|
4948
|
+
/* @__PURE__ */ jsx21(PoweredByBar, { poweredBy: props2.options.poweredBy })
|
|
4065
4949
|
]
|
|
4066
4950
|
}
|
|
4067
4951
|
);
|
|
@@ -4092,13 +4976,39 @@ function PanelContent(props2) {
|
|
|
4092
4976
|
onSend,
|
|
4093
4977
|
onStop,
|
|
4094
4978
|
onSuggestion,
|
|
4979
|
+
intakePending,
|
|
4980
|
+
onIntakeComplete,
|
|
4981
|
+
tool,
|
|
4095
4982
|
containerEl,
|
|
4096
4983
|
dragOver,
|
|
4097
4984
|
composerAttachApiRef
|
|
4098
4985
|
} = props2;
|
|
4099
4986
|
const s = options.strings;
|
|
4100
|
-
|
|
4101
|
-
|
|
4987
|
+
let composerArea;
|
|
4988
|
+
if (intakePending) {
|
|
4989
|
+
composerArea = /* @__PURE__ */ jsx21(IntakeGate, { intake: options.intake, strings: s, onComplete: onIntakeComplete });
|
|
4990
|
+
} else if (canSend) {
|
|
4991
|
+
composerArea = /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
4992
|
+
/* @__PURE__ */ jsx21(Suggestions, { suggestions, onPick: onSuggestion }),
|
|
4993
|
+
/* @__PURE__ */ jsx21(
|
|
4994
|
+
Composer,
|
|
4995
|
+
{
|
|
4996
|
+
options,
|
|
4997
|
+
transport,
|
|
4998
|
+
feedback,
|
|
4999
|
+
bus,
|
|
5000
|
+
isStreaming,
|
|
5001
|
+
onSend,
|
|
5002
|
+
onStop,
|
|
5003
|
+
attachApiRef: composerAttachApiRef
|
|
5004
|
+
}
|
|
5005
|
+
)
|
|
5006
|
+
] });
|
|
5007
|
+
} else {
|
|
5008
|
+
composerArea = /* @__PURE__ */ jsx21(ReadOnlyBanner, { label: s.chatClosed, ctaLabel: s.startNewConversation, onNewChat: onClear });
|
|
5009
|
+
}
|
|
5010
|
+
return /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
5011
|
+
view === "history" ? /* @__PURE__ */ jsx21(
|
|
4102
5012
|
HistoryHeader,
|
|
4103
5013
|
{
|
|
4104
5014
|
strings: s,
|
|
@@ -4106,22 +5016,22 @@ function PanelContent(props2) {
|
|
|
4106
5016
|
onClose,
|
|
4107
5017
|
showClose: canShowClose(options.mode, panelSize, options.actions)
|
|
4108
5018
|
}
|
|
4109
|
-
) : /* @__PURE__ */
|
|
4110
|
-
onBack ? /* @__PURE__ */
|
|
5019
|
+
) : /* @__PURE__ */ jsxs16("header", { class: `${p17}-header`, "data-testid": TID.panelHeader, children: [
|
|
5020
|
+
onBack ? /* @__PURE__ */ jsx21(
|
|
4111
5021
|
"button",
|
|
4112
5022
|
{
|
|
4113
5023
|
type: "button",
|
|
4114
|
-
class: `${
|
|
5024
|
+
class: `${p17}-icon-btn`,
|
|
4115
5025
|
onClick: onBack,
|
|
4116
5026
|
"aria-label": s.moduleBack,
|
|
4117
5027
|
title: s.moduleBack,
|
|
4118
|
-
children: /* @__PURE__ */
|
|
5028
|
+
children: /* @__PURE__ */ jsx21(BackIcon, {})
|
|
4119
5029
|
}
|
|
4120
5030
|
) : null,
|
|
4121
|
-
agent ? /* @__PURE__ */
|
|
4122
|
-
/* @__PURE__ */
|
|
5031
|
+
agent ? /* @__PURE__ */ jsx21(AgentBadge, { agent }) : /* @__PURE__ */ jsx21("h1", { children: s.panelTitle }),
|
|
5032
|
+
/* @__PURE__ */ jsx21(HeaderActions, { panelProps: props2, variant: "chat" })
|
|
4123
5033
|
] }),
|
|
4124
|
-
view === "history" ? /* @__PURE__ */
|
|
5034
|
+
view === "history" ? /* @__PURE__ */ jsx21(
|
|
4125
5035
|
ChatHistoryPane,
|
|
4126
5036
|
{
|
|
4127
5037
|
transport,
|
|
@@ -4130,9 +5040,9 @@ function PanelContent(props2) {
|
|
|
4130
5040
|
onSelect: (chat) => onSelectHistoryChat(chat.sessionId),
|
|
4131
5041
|
onNewChat
|
|
4132
5042
|
}
|
|
4133
|
-
) : /* @__PURE__ */
|
|
4134
|
-
/* @__PURE__ */
|
|
4135
|
-
/* @__PURE__ */
|
|
5043
|
+
) : /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
5044
|
+
/* @__PURE__ */ jsx21(DropZone, { visible: dragOver, strings: s }),
|
|
5045
|
+
/* @__PURE__ */ jsx21(
|
|
4136
5046
|
MessageList,
|
|
4137
5047
|
{
|
|
4138
5048
|
messagesSig,
|
|
@@ -4140,28 +5050,15 @@ function PanelContent(props2) {
|
|
|
4140
5050
|
responseMode: options.responseMode,
|
|
4141
5051
|
showReasoning: options.showReasoning,
|
|
4142
5052
|
showToolCalls: options.showToolCalls,
|
|
4143
|
-
loading: loadingMessages
|
|
5053
|
+
loading: loadingMessages,
|
|
5054
|
+
idle: !isStreaming,
|
|
5055
|
+
tool
|
|
4144
5056
|
}
|
|
4145
5057
|
),
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
/* @__PURE__ */ jsx17(
|
|
4149
|
-
Composer,
|
|
4150
|
-
{
|
|
4151
|
-
options,
|
|
4152
|
-
transport,
|
|
4153
|
-
feedback,
|
|
4154
|
-
bus,
|
|
4155
|
-
isStreaming,
|
|
4156
|
-
onSend,
|
|
4157
|
-
onStop,
|
|
4158
|
-
attachApiRef: composerAttachApiRef
|
|
4159
|
-
}
|
|
4160
|
-
)
|
|
4161
|
-
] }) : /* @__PURE__ */ jsx17(ReadOnlyBanner, { label: s.chatClosed, ctaLabel: s.startNewConversation, onNewChat: onClear }),
|
|
4162
|
-
/* @__PURE__ */ jsx17(ComposerFooter, { disclaimer: options.composerDisclaimer })
|
|
5058
|
+
composerArea,
|
|
5059
|
+
/* @__PURE__ */ jsx21(ComposerFooter, { disclaimer: options.composerDisclaimer })
|
|
4163
5060
|
] }),
|
|
4164
|
-
options.size.resize?.enabled ? /* @__PURE__ */
|
|
5061
|
+
options.size.resize?.enabled ? /* @__PURE__ */ jsx21(
|
|
4165
5062
|
ResizeGrip,
|
|
4166
5063
|
{
|
|
4167
5064
|
panelEl: containerEl,
|
|
@@ -4180,86 +5077,86 @@ function HistoryHeader({
|
|
|
4180
5077
|
onClose,
|
|
4181
5078
|
showClose
|
|
4182
5079
|
}) {
|
|
4183
|
-
return /* @__PURE__ */
|
|
4184
|
-
/* @__PURE__ */
|
|
5080
|
+
return /* @__PURE__ */ jsxs16("header", { class: `${p17}-header`, children: [
|
|
5081
|
+
/* @__PURE__ */ jsx21(
|
|
4185
5082
|
"button",
|
|
4186
5083
|
{
|
|
4187
5084
|
type: "button",
|
|
4188
|
-
class: `${
|
|
5085
|
+
class: `${p17}-icon-btn`,
|
|
4189
5086
|
onClick: onBack,
|
|
4190
5087
|
"aria-label": strings.historyBack,
|
|
4191
5088
|
title: strings.historyBack,
|
|
4192
|
-
children: /* @__PURE__ */
|
|
5089
|
+
children: /* @__PURE__ */ jsx21(BackIcon, {})
|
|
4193
5090
|
}
|
|
4194
5091
|
),
|
|
4195
|
-
/* @__PURE__ */
|
|
4196
|
-
showClose ? /* @__PURE__ */
|
|
5092
|
+
/* @__PURE__ */ jsx21("h1", { children: strings.historyTitle }),
|
|
5093
|
+
showClose ? /* @__PURE__ */ jsx21(
|
|
4197
5094
|
"button",
|
|
4198
5095
|
{
|
|
4199
5096
|
type: "button",
|
|
4200
|
-
class: `${
|
|
5097
|
+
class: `${p17}-icon-btn`,
|
|
4201
5098
|
onClick: onClose,
|
|
4202
5099
|
"aria-label": strings.close,
|
|
4203
5100
|
title: strings.close,
|
|
4204
|
-
children: /* @__PURE__ */
|
|
5101
|
+
children: /* @__PURE__ */ jsx21(CloseIcon, {})
|
|
4205
5102
|
}
|
|
4206
5103
|
) : null
|
|
4207
5104
|
] });
|
|
4208
5105
|
}
|
|
4209
5106
|
function ReadOnlyBanner({ label, ctaLabel, onNewChat }) {
|
|
4210
|
-
return /* @__PURE__ */
|
|
4211
|
-
/* @__PURE__ */
|
|
4212
|
-
/* @__PURE__ */
|
|
5107
|
+
return /* @__PURE__ */ jsxs16("div", { class: `${p17}-readonly-banner`, role: "note", children: [
|
|
5108
|
+
/* @__PURE__ */ jsx21("span", { class: `${p17}-readonly-label`, children: label }),
|
|
5109
|
+
/* @__PURE__ */ jsx21("button", { type: "button", class: `${p17}-readonly-cta`, onClick: onNewChat, children: ctaLabel })
|
|
4213
5110
|
] });
|
|
4214
5111
|
}
|
|
4215
5112
|
function ComposerFooter({ disclaimer }) {
|
|
4216
5113
|
if (!disclaimer) return null;
|
|
4217
|
-
return /* @__PURE__ */
|
|
5114
|
+
return /* @__PURE__ */ jsx21("div", { class: `${p17}-composer-footer`, children: /* @__PURE__ */ jsx21("div", { class: `${p17}-disclaimer`, children: disclaimer }) });
|
|
4218
5115
|
}
|
|
4219
5116
|
function PoweredByBar({ poweredBy }) {
|
|
4220
5117
|
if (!poweredBy) return null;
|
|
4221
|
-
return /* @__PURE__ */
|
|
5118
|
+
return /* @__PURE__ */ jsx21("div", { class: `${p17}-poweredby-bar`, children: /* @__PURE__ */ jsx21(PoweredBy, { logoUrl: poweredBy.logoUrl, text: poweredBy.text, href: poweredBy.href }) });
|
|
4222
5119
|
}
|
|
4223
5120
|
function PoweredBy({ logoUrl, text, href }) {
|
|
4224
|
-
const inner = /* @__PURE__ */
|
|
4225
|
-
logoUrl ? /* @__PURE__ */
|
|
4226
|
-
text ? /* @__PURE__ */
|
|
5121
|
+
const inner = /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
5122
|
+
logoUrl ? /* @__PURE__ */ jsx21("img", { class: `${p17}-poweredby-logo`, src: logoUrl, alt: "", loading: "lazy" }) : null,
|
|
5123
|
+
text ? /* @__PURE__ */ jsx21("span", { children: text }) : null
|
|
4227
5124
|
] });
|
|
4228
5125
|
if (href) {
|
|
4229
|
-
return /* @__PURE__ */
|
|
5126
|
+
return /* @__PURE__ */ jsx21("a", { class: `${p17}-poweredby`, href, target: "_blank", rel: "noopener noreferrer", children: inner });
|
|
4230
5127
|
}
|
|
4231
|
-
return /* @__PURE__ */
|
|
5128
|
+
return /* @__PURE__ */ jsx21("span", { class: `${p17}-poweredby`, children: inner });
|
|
4232
5129
|
}
|
|
4233
5130
|
|
|
4234
5131
|
// src/ui/sidebar.tsx
|
|
4235
|
-
import { Fragment as
|
|
5132
|
+
import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs17 } from "preact/jsx-runtime";
|
|
4236
5133
|
function Sidebar(props2) {
|
|
4237
|
-
const
|
|
5134
|
+
const p33 = BRAND.cssPrefix;
|
|
4238
5135
|
const { site, blocks, strings, collapsed } = props2;
|
|
4239
5136
|
const navigation = blocks?.navigation ?? [];
|
|
4240
5137
|
const linkCards = blocks?.linkCards ?? [];
|
|
4241
5138
|
const toggleLabel = collapsed ? strings.expandSidebar : strings.collapseSidebar;
|
|
4242
|
-
return /* @__PURE__ */
|
|
4243
|
-
/* @__PURE__ */
|
|
4244
|
-
/* @__PURE__ */
|
|
4245
|
-
/* @__PURE__ */
|
|
5139
|
+
return /* @__PURE__ */ jsxs17("aside", { class: `${p33}-sidebar`, "data-collapsed": collapsed ? "true" : "false", "data-testid": TID.sidebar, children: [
|
|
5140
|
+
/* @__PURE__ */ jsxs17("div", { class: `${p33}-sidebar-header`, children: [
|
|
5141
|
+
/* @__PURE__ */ jsx22(SidebarBrand, { site }),
|
|
5142
|
+
/* @__PURE__ */ jsx22(
|
|
4246
5143
|
"button",
|
|
4247
5144
|
{
|
|
4248
5145
|
type: "button",
|
|
4249
|
-
class: `${
|
|
5146
|
+
class: `${p33}-sidebar-toggle`,
|
|
4250
5147
|
"aria-label": toggleLabel,
|
|
4251
5148
|
"aria-expanded": collapsed ? "false" : "true",
|
|
4252
5149
|
title: toggleLabel,
|
|
4253
5150
|
onClick: props2.onToggleCollapsed,
|
|
4254
5151
|
"data-testid": TID.sidebarToggle,
|
|
4255
|
-
children: /* @__PURE__ */
|
|
5152
|
+
children: /* @__PURE__ */ jsx22(SidebarToggleIcon, { collapsed })
|
|
4256
5153
|
}
|
|
4257
5154
|
)
|
|
4258
5155
|
] }),
|
|
4259
|
-
collapsed ? null : /* @__PURE__ */
|
|
4260
|
-
navigation.length > 0 ? /* @__PURE__ */
|
|
4261
|
-
linkCards.length > 0 ? /* @__PURE__ */
|
|
4262
|
-
props2.showConversations ? /* @__PURE__ */
|
|
5156
|
+
collapsed ? null : /* @__PURE__ */ jsxs17(Fragment4, { children: [
|
|
5157
|
+
navigation.length > 0 ? /* @__PURE__ */ jsx22("nav", { class: `${p33}-sidebar-section`, "data-section": "navigation", children: /* @__PURE__ */ jsx22(SidebarNav, { items: navigation }) }) : null,
|
|
5158
|
+
linkCards.length > 0 ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-section`, "data-section": "link-cards", children: /* @__PURE__ */ jsx22(SidebarCards, { items: linkCards }) }) : null,
|
|
5159
|
+
props2.showConversations ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-conversations`, children: /* @__PURE__ */ jsx22(
|
|
4263
5160
|
ConversationList,
|
|
4264
5161
|
{
|
|
4265
5162
|
transport: props2.transport,
|
|
@@ -4273,18 +5170,18 @@ function Sidebar(props2) {
|
|
|
4273
5170
|
] });
|
|
4274
5171
|
}
|
|
4275
5172
|
function SidebarBrand({ site }) {
|
|
4276
|
-
const
|
|
5173
|
+
const p33 = BRAND.cssPrefix;
|
|
4277
5174
|
if (site?.logo?.url) {
|
|
4278
5175
|
const alt = site.logo.alt ?? site.title ?? "Logo";
|
|
4279
|
-
return /* @__PURE__ */
|
|
4280
|
-
site.logoDark?.url ? /* @__PURE__ */
|
|
4281
|
-
/* @__PURE__ */
|
|
5176
|
+
return /* @__PURE__ */ jsxs17("picture", { children: [
|
|
5177
|
+
site.logoDark?.url ? /* @__PURE__ */ jsx22("source", { srcset: site.logoDark.url, media: "(prefers-color-scheme: dark)" }) : null,
|
|
5178
|
+
/* @__PURE__ */ jsx22("img", { class: `${p33}-sidebar-logo`, src: site.logo.url, alt })
|
|
4282
5179
|
] });
|
|
4283
5180
|
}
|
|
4284
|
-
return /* @__PURE__ */
|
|
5181
|
+
return /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-title`, children: site?.title ?? BRAND.name });
|
|
4285
5182
|
}
|
|
4286
5183
|
function SidebarToggleIcon({ collapsed }) {
|
|
4287
|
-
return /* @__PURE__ */
|
|
5184
|
+
return /* @__PURE__ */ jsx22(
|
|
4288
5185
|
"svg",
|
|
4289
5186
|
{
|
|
4290
5187
|
width: "16",
|
|
@@ -4294,38 +5191,38 @@ function SidebarToggleIcon({ collapsed }) {
|
|
|
4294
5191
|
stroke: "currentColor",
|
|
4295
5192
|
"stroke-width": "2",
|
|
4296
5193
|
"aria-hidden": "true",
|
|
4297
|
-
children: collapsed ? /* @__PURE__ */
|
|
5194
|
+
children: collapsed ? /* @__PURE__ */ jsx22("polyline", { points: "9 6 15 12 9 18" }) : /* @__PURE__ */ jsx22("polyline", { points: "15 6 9 12 15 18" })
|
|
4298
5195
|
}
|
|
4299
5196
|
);
|
|
4300
5197
|
}
|
|
4301
5198
|
function SidebarNav({ items }) {
|
|
4302
|
-
const
|
|
4303
|
-
return /* @__PURE__ */
|
|
5199
|
+
const p33 = BRAND.cssPrefix;
|
|
5200
|
+
return /* @__PURE__ */ jsx22("ul", { class: `${p33}-sidebar-nav`, children: items.map((item) => /* @__PURE__ */ jsx22("li", { children: /* @__PURE__ */ jsxs17(
|
|
4304
5201
|
"a",
|
|
4305
5202
|
{
|
|
4306
|
-
class: `${
|
|
5203
|
+
class: `${p33}-sidebar-nav-item`,
|
|
4307
5204
|
href: item.href,
|
|
4308
5205
|
target: item.href ? "_blank" : void 0,
|
|
4309
5206
|
rel: item.href ? "noreferrer" : void 0,
|
|
4310
5207
|
children: [
|
|
4311
|
-
item.icon ? /* @__PURE__ */
|
|
4312
|
-
/* @__PURE__ */
|
|
5208
|
+
item.icon ? /* @__PURE__ */ jsx22("span", { class: `${p33}-sidebar-nav-icon`, "data-icon": item.icon }) : null,
|
|
5209
|
+
/* @__PURE__ */ jsx22("span", { class: `${p33}-sidebar-nav-label`, children: item.label })
|
|
4313
5210
|
]
|
|
4314
5211
|
}
|
|
4315
5212
|
) }, item.id ?? item.label)) });
|
|
4316
5213
|
}
|
|
4317
5214
|
function SidebarCards({ items }) {
|
|
4318
|
-
const
|
|
4319
|
-
return /* @__PURE__ */
|
|
5215
|
+
const p33 = BRAND.cssPrefix;
|
|
5216
|
+
return /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-cards`, children: items.map((item) => /* @__PURE__ */ jsxs17(
|
|
4320
5217
|
"a",
|
|
4321
5218
|
{
|
|
4322
|
-
class: `${
|
|
5219
|
+
class: `${p33}-sidebar-card`,
|
|
4323
5220
|
href: item.href,
|
|
4324
5221
|
target: item.href ? "_blank" : void 0,
|
|
4325
5222
|
rel: item.href ? "noreferrer" : void 0,
|
|
4326
5223
|
children: [
|
|
4327
|
-
/* @__PURE__ */
|
|
4328
|
-
item.description ? /* @__PURE__ */
|
|
5224
|
+
/* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-card-label`, children: item.label }),
|
|
5225
|
+
item.description ? /* @__PURE__ */ jsx22("div", { class: `${p33}-sidebar-card-desc`, children: item.description }) : null
|
|
4329
5226
|
]
|
|
4330
5227
|
},
|
|
4331
5228
|
item.id ?? item.label
|
|
@@ -4333,11 +5230,11 @@ function SidebarCards({ items }) {
|
|
|
4333
5230
|
}
|
|
4334
5231
|
|
|
4335
5232
|
// src/ui/page-shell.tsx
|
|
4336
|
-
import { jsx as
|
|
4337
|
-
var
|
|
5233
|
+
import { jsx as jsx23, jsxs as jsxs18 } from "preact/jsx-runtime";
|
|
5234
|
+
var p18 = BRAND.cssPrefix;
|
|
4338
5235
|
function PageShell(props2) {
|
|
4339
|
-
return /* @__PURE__ */
|
|
4340
|
-
/* @__PURE__ */
|
|
5236
|
+
return /* @__PURE__ */ jsxs18("main", { class: `${p18}-page-shell`, "data-sidebar-collapsed": props2.sidebarCollapsed ? "true" : "false", children: [
|
|
5237
|
+
/* @__PURE__ */ jsx23(
|
|
4341
5238
|
Sidebar,
|
|
4342
5239
|
{
|
|
4343
5240
|
site: props2.site,
|
|
@@ -4352,7 +5249,7 @@ function PageShell(props2) {
|
|
|
4352
5249
|
onToggleCollapsed: props2.onToggleSidebarCollapsed
|
|
4353
5250
|
}
|
|
4354
5251
|
),
|
|
4355
|
-
/* @__PURE__ */
|
|
5252
|
+
/* @__PURE__ */ jsx23("section", { class: `${p18}-page-chat`, "aria-label": "Chat", children: props2.children })
|
|
4356
5253
|
] });
|
|
4357
5254
|
}
|
|
4358
5255
|
|
|
@@ -4390,7 +5287,7 @@ var atTabRoot = (s) => activeStack(s).length === 0;
|
|
|
4390
5287
|
|
|
4391
5288
|
// src/ui/messenger-home.tsx
|
|
4392
5289
|
import { useCallback as useCallback4, useEffect as useEffect15, useRef as useRef7 } from "preact/hooks";
|
|
4393
|
-
import { useComputed as
|
|
5290
|
+
import { useComputed as useComputed6 } from "@preact/signals";
|
|
4394
5291
|
|
|
4395
5292
|
// src/ui/modules/messages.tsx
|
|
4396
5293
|
var chatLayout = {
|
|
@@ -4399,83 +5296,83 @@ var chatLayout = {
|
|
|
4399
5296
|
};
|
|
4400
5297
|
|
|
4401
5298
|
// src/ui/modules/help.tsx
|
|
4402
|
-
import { useEffect as useEffect11, useMemo as useMemo2, useState as
|
|
5299
|
+
import { useEffect as useEffect11, useMemo as useMemo2, useState as useState8 } from "preact/hooks";
|
|
4403
5300
|
|
|
4404
5301
|
// src/ui/back-header.tsx
|
|
4405
|
-
import { jsx as
|
|
4406
|
-
var
|
|
5302
|
+
import { jsx as jsx24, jsxs as jsxs19 } from "preact/jsx-runtime";
|
|
5303
|
+
var p19 = BRAND.cssPrefix;
|
|
4407
5304
|
function TitleBar({ title, actions }) {
|
|
4408
|
-
return /* @__PURE__ */
|
|
4409
|
-
/* @__PURE__ */
|
|
4410
|
-
/* @__PURE__ */
|
|
4411
|
-
actions ?? /* @__PURE__ */
|
|
5305
|
+
return /* @__PURE__ */ jsxs19("header", { class: `${p19}-back-header`, "data-variant": "title", children: [
|
|
5306
|
+
/* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" }),
|
|
5307
|
+
/* @__PURE__ */ jsx24("h1", { class: `${p19}-back-title`, children: title }),
|
|
5308
|
+
actions ?? /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" })
|
|
4412
5309
|
] });
|
|
4413
5310
|
}
|
|
4414
5311
|
function BackHeader({ title, backLabel, onBack, actions, testid }) {
|
|
4415
|
-
return /* @__PURE__ */
|
|
4416
|
-
/* @__PURE__ */
|
|
4417
|
-
/* @__PURE__ */
|
|
4418
|
-
actions ?? /* @__PURE__ */
|
|
5312
|
+
return /* @__PURE__ */ jsxs19("header", { class: `${p19}-back-header`, "data-testid": testid, children: [
|
|
5313
|
+
/* @__PURE__ */ jsx24("button", { type: "button", class: `${p19}-icon-btn`, onClick: onBack, "aria-label": backLabel, title: backLabel, children: /* @__PURE__ */ jsx24(BackIcon, {}) }),
|
|
5314
|
+
/* @__PURE__ */ jsx24("h1", { class: `${p19}-back-title`, children: title }),
|
|
5315
|
+
actions ?? /* @__PURE__ */ jsx24("span", { class: `${p19}-back-spacer`, "aria-hidden": "true" })
|
|
4419
5316
|
] });
|
|
4420
5317
|
}
|
|
4421
5318
|
|
|
4422
5319
|
// src/ui/home-search.tsx
|
|
4423
|
-
import { jsx as
|
|
4424
|
-
var
|
|
5320
|
+
import { jsx as jsx25, jsxs as jsxs20 } from "preact/jsx-runtime";
|
|
5321
|
+
var p20 = BRAND.cssPrefix;
|
|
4425
5322
|
function HomeSearchButton({ placeholder, onActivate }) {
|
|
4426
|
-
return /* @__PURE__ */
|
|
4427
|
-
/* @__PURE__ */
|
|
4428
|
-
/* @__PURE__ */
|
|
5323
|
+
return /* @__PURE__ */ jsxs20("button", { type: "button", class: `${p20}-home-search`, onClick: onActivate, "data-testid": TID.homeSearch, children: [
|
|
5324
|
+
/* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-text`, children: placeholder }),
|
|
5325
|
+
/* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx25(SearchIcon, {}) })
|
|
4429
5326
|
] });
|
|
4430
5327
|
}
|
|
4431
5328
|
function HelpSearchInput({ placeholder, value, onInput }) {
|
|
4432
|
-
return /* @__PURE__ */
|
|
4433
|
-
/* @__PURE__ */
|
|
5329
|
+
return /* @__PURE__ */ jsxs20("div", { class: `${p20}-home-search`, "data-input": "true", children: [
|
|
5330
|
+
/* @__PURE__ */ jsx25(
|
|
4434
5331
|
"input",
|
|
4435
5332
|
{
|
|
4436
5333
|
type: "search",
|
|
4437
|
-
class: `${
|
|
5334
|
+
class: `${p20}-home-search-input`,
|
|
4438
5335
|
placeholder,
|
|
4439
5336
|
value,
|
|
4440
5337
|
onInput: (e) => onInput(e.currentTarget.value),
|
|
4441
5338
|
"data-testid": TID.helpSearch
|
|
4442
5339
|
}
|
|
4443
5340
|
),
|
|
4444
|
-
/* @__PURE__ */
|
|
5341
|
+
/* @__PURE__ */ jsx25("span", { class: `${p20}-home-search-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx25(SearchIcon, {}) })
|
|
4445
5342
|
] });
|
|
4446
5343
|
}
|
|
4447
5344
|
|
|
4448
5345
|
// src/ui/list-row.tsx
|
|
4449
|
-
import { jsx as
|
|
4450
|
-
var
|
|
5346
|
+
import { jsx as jsx26, jsxs as jsxs21 } from "preact/jsx-runtime";
|
|
5347
|
+
var p21 = BRAND.cssPrefix;
|
|
4451
5348
|
function ListRow({ title, subtitle, onClick, testid }) {
|
|
4452
|
-
return /* @__PURE__ */
|
|
4453
|
-
/* @__PURE__ */
|
|
4454
|
-
/* @__PURE__ */
|
|
4455
|
-
subtitle ? /* @__PURE__ */
|
|
5349
|
+
return /* @__PURE__ */ jsxs21("button", { type: "button", class: `${p21}-list-row`, onClick, "data-testid": testid, children: [
|
|
5350
|
+
/* @__PURE__ */ jsxs21("span", { class: `${p21}-list-row-body`, children: [
|
|
5351
|
+
/* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-title`, children: title }),
|
|
5352
|
+
subtitle ? /* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-sub`, children: subtitle }) : null
|
|
4456
5353
|
] }),
|
|
4457
|
-
/* @__PURE__ */
|
|
5354
|
+
/* @__PURE__ */ jsx26("span", { class: `${p21}-list-row-chevron`, "aria-hidden": "true", children: /* @__PURE__ */ jsx26(ChevronRightIcon, {}) })
|
|
4458
5355
|
] });
|
|
4459
5356
|
}
|
|
4460
5357
|
|
|
4461
5358
|
// src/ui/module-state.tsx
|
|
4462
|
-
import { jsx as
|
|
4463
|
-
var
|
|
5359
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "preact/jsx-runtime";
|
|
5360
|
+
var p22 = BRAND.cssPrefix;
|
|
4464
5361
|
function ModuleState({
|
|
4465
5362
|
tone = "info",
|
|
4466
5363
|
message,
|
|
4467
5364
|
onRetry,
|
|
4468
5365
|
strings
|
|
4469
5366
|
}) {
|
|
4470
|
-
return /* @__PURE__ */
|
|
4471
|
-
/* @__PURE__ */
|
|
4472
|
-
onRetry ? /* @__PURE__ */
|
|
5367
|
+
return /* @__PURE__ */ jsxs22("div", { class: `${p22}-module-empty`, role: tone === "error" ? "alert" : "status", "aria-live": "polite", children: [
|
|
5368
|
+
/* @__PURE__ */ jsx27("span", { children: message }),
|
|
5369
|
+
onRetry ? /* @__PURE__ */ jsx27("button", { type: "button", class: `${p22}-module-retry`, onClick: onRetry, children: strings.errorRetry }) : null
|
|
4473
5370
|
] });
|
|
4474
5371
|
}
|
|
4475
5372
|
|
|
4476
5373
|
// src/ui/modules/help.tsx
|
|
4477
|
-
import { jsx as
|
|
4478
|
-
var
|
|
5374
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "preact/jsx-runtime";
|
|
5375
|
+
var p23 = BRAND.cssPrefix;
|
|
4479
5376
|
var log12 = logger.scope("help");
|
|
4480
5377
|
var openArticle = (nav, a) => a.url ? nav.push({ kind: "iframe", url: a.url, title: a.title }) : nav.push({ kind: "content", id: a.id, title: a.title });
|
|
4481
5378
|
function groupByCategory(items) {
|
|
@@ -4504,7 +5401,7 @@ function fuzzySearch(items, query) {
|
|
|
4504
5401
|
return items.map((item) => ({ item, score: Math.max(fuzzyScore(q, item.title) * 2, fuzzyScore(q, item.description ?? "")) })).filter((r) => r.score > 0).toSorted((a, b) => b.score - a.score).map((r) => r.item);
|
|
4505
5402
|
}
|
|
4506
5403
|
function ArticleRow({ article, nav }) {
|
|
4507
|
-
return /* @__PURE__ */
|
|
5404
|
+
return /* @__PURE__ */ jsx28(
|
|
4508
5405
|
ListRow,
|
|
4509
5406
|
{
|
|
4510
5407
|
title: article.title,
|
|
@@ -4516,11 +5413,11 @@ function ArticleRow({ article, nav }) {
|
|
|
4516
5413
|
}
|
|
4517
5414
|
function HelpRoot({ transport, strings, config, nav, panelProps }) {
|
|
4518
5415
|
const tags = config.contentTags;
|
|
4519
|
-
const [state, setState] =
|
|
4520
|
-
const [errorMsg, setErrorMsg] =
|
|
4521
|
-
const [items, setItems] =
|
|
4522
|
-
const [query, setQuery] =
|
|
4523
|
-
const [reloadKey, setReloadKey] =
|
|
5416
|
+
const [state, setState] = useState8("loading");
|
|
5417
|
+
const [errorMsg, setErrorMsg] = useState8(strings.errorGeneric);
|
|
5418
|
+
const [items, setItems] = useState8([]);
|
|
5419
|
+
const [query, setQuery] = useState8("");
|
|
5420
|
+
const [reloadKey, setReloadKey] = useState8(0);
|
|
4524
5421
|
useEffect11(() => {
|
|
4525
5422
|
let cancelled = false;
|
|
4526
5423
|
setState("loading");
|
|
@@ -4541,46 +5438,46 @@ function HelpRoot({ transport, strings, config, nav, panelProps }) {
|
|
|
4541
5438
|
const results = useMemo2(() => fuzzySearch(items, query), [items, query]);
|
|
4542
5439
|
function renderBody() {
|
|
4543
5440
|
if (query.trim().length > 0) {
|
|
4544
|
-
if (results.length === 0) return /* @__PURE__ */
|
|
4545
|
-
return /* @__PURE__ */
|
|
5441
|
+
if (results.length === 0) return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpSearchEmpty, strings });
|
|
5442
|
+
return /* @__PURE__ */ jsx28("div", { class: `${p23}-help-card`, children: results.map((a) => /* @__PURE__ */ jsx28(ArticleRow, { article: a, nav }, a.id)) });
|
|
4546
5443
|
}
|
|
4547
|
-
if (state === "loading") return /* @__PURE__ */
|
|
5444
|
+
if (state === "loading") return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpLoading, strings });
|
|
4548
5445
|
if (state === "error") {
|
|
4549
|
-
return /* @__PURE__ */
|
|
5446
|
+
return /* @__PURE__ */ jsx28(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
|
|
4550
5447
|
}
|
|
4551
|
-
if (items.length === 0) return /* @__PURE__ */
|
|
4552
|
-
return groupByCategory(items).map(([category, rows]) => /* @__PURE__ */
|
|
4553
|
-
category ? /* @__PURE__ */
|
|
4554
|
-
/* @__PURE__ */
|
|
5448
|
+
if (items.length === 0) return /* @__PURE__ */ jsx28(ModuleState, { message: strings.helpEmpty, strings });
|
|
5449
|
+
return groupByCategory(items).map(([category, rows]) => /* @__PURE__ */ jsxs23("section", { class: `${p23}-help-group`, children: [
|
|
5450
|
+
category ? /* @__PURE__ */ jsx28("h2", { class: `${p23}-help-section-title`, children: category }) : null,
|
|
5451
|
+
/* @__PURE__ */ jsx28("div", { class: `${p23}-help-card`, children: rows.map((a) => /* @__PURE__ */ jsx28(ArticleRow, { article: a, nav }, a.id)) })
|
|
4555
5452
|
] }, category));
|
|
4556
5453
|
}
|
|
4557
|
-
return /* @__PURE__ */
|
|
4558
|
-
/* @__PURE__ */
|
|
4559
|
-
/* @__PURE__ */
|
|
4560
|
-
/* @__PURE__ */
|
|
5454
|
+
return /* @__PURE__ */ jsxs23("div", { class: `${p23}-module`, children: [
|
|
5455
|
+
/* @__PURE__ */ jsx28(TitleBar, { title: strings.helpTitle, actions: /* @__PURE__ */ jsx28(HeaderActions, { panelProps, variant: "plain" }) }),
|
|
5456
|
+
/* @__PURE__ */ jsx28("div", { class: `${p23}-module-pad`, children: /* @__PURE__ */ jsx28(HelpSearchInput, { placeholder: strings.helpSearchPlaceholder, value: query, onInput: setQuery }) }),
|
|
5457
|
+
/* @__PURE__ */ jsx28("div", { class: `${p23}-help-list`, children: renderBody() })
|
|
4561
5458
|
] });
|
|
4562
5459
|
}
|
|
4563
5460
|
var helpLayout = {
|
|
4564
5461
|
Icon: HelpIcon,
|
|
4565
|
-
Root: (props2) => /* @__PURE__ */
|
|
5462
|
+
Root: (props2) => /* @__PURE__ */ jsx28(HelpRoot, { ...props2 })
|
|
4566
5463
|
};
|
|
4567
5464
|
|
|
4568
5465
|
// src/ui/modules/home.tsx
|
|
4569
|
-
import { useEffect as useEffect12, useState as
|
|
5466
|
+
import { useEffect as useEffect12, useState as useState9 } from "preact/hooks";
|
|
4570
5467
|
|
|
4571
5468
|
// src/ui/home-card.tsx
|
|
4572
|
-
import { jsx as
|
|
4573
|
-
var
|
|
5469
|
+
import { jsx as jsx29 } from "preact/jsx-runtime";
|
|
5470
|
+
var p24 = BRAND.cssPrefix;
|
|
4574
5471
|
function HomeCard({ onClick, children, testid }) {
|
|
4575
5472
|
if (onClick) {
|
|
4576
|
-
return /* @__PURE__ */
|
|
5473
|
+
return /* @__PURE__ */ jsx29("button", { type: "button", class: `${p24}-home-card`, "data-interactive": "true", onClick, "data-testid": testid, children });
|
|
4577
5474
|
}
|
|
4578
|
-
return /* @__PURE__ */
|
|
5475
|
+
return /* @__PURE__ */ jsx29("div", { class: `${p24}-home-card`, "data-testid": testid, children });
|
|
4579
5476
|
}
|
|
4580
5477
|
|
|
4581
5478
|
// src/ui/modules/home.tsx
|
|
4582
|
-
import { Fragment as
|
|
4583
|
-
var
|
|
5479
|
+
import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs24 } from "preact/jsx-runtime";
|
|
5480
|
+
var p25 = BRAND.cssPrefix;
|
|
4584
5481
|
var log13 = logger.scope("home");
|
|
4585
5482
|
function resolveGreeting(props2) {
|
|
4586
5483
|
const name = props2.options.userContext?.name;
|
|
@@ -4594,8 +5491,8 @@ function resolveGreeting(props2) {
|
|
|
4594
5491
|
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 });
|
|
4595
5492
|
function HomeRoot(props2) {
|
|
4596
5493
|
const { transport, strings, config, nav, panelProps } = props2;
|
|
4597
|
-
const [recent, setRecent] =
|
|
4598
|
-
const [content, setContent] =
|
|
5494
|
+
const [recent, setRecent] = useState9(null);
|
|
5495
|
+
const [content, setContent] = useState9([]);
|
|
4599
5496
|
const tagsKey = config.contentTags?.join(",");
|
|
4600
5497
|
useEffect12(() => {
|
|
4601
5498
|
if (!config.showRecentMessages) return;
|
|
@@ -4617,49 +5514,49 @@ function HomeRoot(props2) {
|
|
|
4617
5514
|
const avatars = config.userAvatars ?? [];
|
|
4618
5515
|
const status = config.status;
|
|
4619
5516
|
const contentTitle = config.contentBlockTitle ? moduleLabel(strings, config.contentBlockTitle) : strings.homeContentTitle;
|
|
4620
|
-
return /* @__PURE__ */
|
|
4621
|
-
/* @__PURE__ */
|
|
4622
|
-
/* @__PURE__ */
|
|
4623
|
-
config.brandName ? /* @__PURE__ */
|
|
4624
|
-
/* @__PURE__ */
|
|
4625
|
-
avatars.length > 0 ? /* @__PURE__ */
|
|
4626
|
-
/* @__PURE__ */
|
|
5517
|
+
return /* @__PURE__ */ jsx30("div", { class: `${p25}-module ${p25}-home`, "data-testid": TID.homeView, children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-scroll`, children: [
|
|
5518
|
+
/* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero`, children: [
|
|
5519
|
+
/* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-top`, children: [
|
|
5520
|
+
config.brandName ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-brand`, "data-testid": TID.homeBrand, children: config.brandName }) : /* @__PURE__ */ jsx30("span", { class: `${p25}-home-brand-spacer`, "aria-hidden": "true" }),
|
|
5521
|
+
/* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-actions`, children: [
|
|
5522
|
+
avatars.length > 0 ? /* @__PURE__ */ jsx30("div", { class: `${p25}-home-avatars`, children: avatars.map((a) => /* @__PURE__ */ jsx30("span", { class: `${p25}-home-avatar`, title: a.role ? `${a.name} \xB7 ${a.role}` : a.name, children: a.avatar ? /* @__PURE__ */ jsx30("img", { src: a.avatar, alt: "", loading: "lazy" }) : /* @__PURE__ */ jsx30("span", { children: initials(a.name) }) }, a.name)) }) : null,
|
|
5523
|
+
/* @__PURE__ */ jsx30(HeaderActions, { panelProps, variant: "plain" })
|
|
4627
5524
|
] })
|
|
4628
5525
|
] }),
|
|
4629
|
-
config.showGreeting !== false ? /* @__PURE__ */
|
|
4630
|
-
/* @__PURE__ */
|
|
4631
|
-
greeting.subtitle ? /* @__PURE__ */
|
|
5526
|
+
config.showGreeting !== false ? /* @__PURE__ */ jsxs24(Fragment5, { children: [
|
|
5527
|
+
/* @__PURE__ */ jsx30("h1", { class: `${p25}-home-greeting`, "data-testid": TID.homeGreeting, children: greeting.title }),
|
|
5528
|
+
greeting.subtitle ? /* @__PURE__ */ jsx30("p", { class: `${p25}-home-lead`, children: greeting.subtitle }) : null
|
|
4632
5529
|
] }) : null
|
|
4633
5530
|
] }),
|
|
4634
|
-
/* @__PURE__ */
|
|
4635
|
-
config.showSearchBar !== false ? /* @__PURE__ */
|
|
5531
|
+
/* @__PURE__ */ jsxs24("div", { class: `${p25}-home-cards`, children: [
|
|
5532
|
+
config.showSearchBar !== false ? /* @__PURE__ */ jsx30(
|
|
4636
5533
|
HomeSearchButton,
|
|
4637
5534
|
{
|
|
4638
5535
|
placeholder: strings.homeSearchPlaceholder,
|
|
4639
5536
|
onActivate: () => nav.switchToLayout("help")
|
|
4640
5537
|
}
|
|
4641
5538
|
) : null,
|
|
4642
|
-
recent ? /* @__PURE__ */
|
|
4643
|
-
/* @__PURE__ */
|
|
4644
|
-
/* @__PURE__ */
|
|
4645
|
-
/* @__PURE__ */
|
|
4646
|
-
recent.preview ? /* @__PURE__ */
|
|
5539
|
+
recent ? /* @__PURE__ */ jsx30(HomeCard, { onClick: () => nav.selectSession(recent.sessionId), testid: TID.homeRecent, children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-recent-row`, "data-unread": (recent.unreadCount ?? 0) > 0 ? "true" : void 0, children: [
|
|
5540
|
+
/* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-avatar`, "aria-hidden": "true", children: /* @__PURE__ */ jsx30(BubblesIcon, {}) }),
|
|
5541
|
+
/* @__PURE__ */ jsxs24("span", { class: `${p25}-home-recent-body`, children: [
|
|
5542
|
+
/* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-title`, children: recent.title }),
|
|
5543
|
+
recent.preview ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-preview`, children: recent.preview }) : null
|
|
4647
5544
|
] }),
|
|
4648
|
-
(recent.unreadCount ?? 0) > 0 ? /* @__PURE__ */
|
|
5545
|
+
(recent.unreadCount ?? 0) > 0 ? /* @__PURE__ */ jsx30("span", { class: `${p25}-home-recent-dot`, "aria-label": "Unread" }) : null
|
|
4649
5546
|
] }) }) : null,
|
|
4650
|
-
status ? /* @__PURE__ */
|
|
5547
|
+
status ? /* @__PURE__ */ jsx30(
|
|
4651
5548
|
HomeCard,
|
|
4652
5549
|
{
|
|
4653
5550
|
onClick: status.url ? () => nav.push({ kind: "iframe", url: status.url, title: status.text }) : void 0,
|
|
4654
|
-
children: /* @__PURE__ */
|
|
4655
|
-
/* @__PURE__ */
|
|
4656
|
-
/* @__PURE__ */
|
|
5551
|
+
children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-status`, "data-level": status.level ?? "operational", children: [
|
|
5552
|
+
/* @__PURE__ */ jsx30("span", { class: `${p25}-home-status-icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx30(StatusOkIcon, {}) }),
|
|
5553
|
+
/* @__PURE__ */ jsx30("span", { class: `${p25}-home-status-text`, children: status.text })
|
|
4657
5554
|
] })
|
|
4658
5555
|
}
|
|
4659
5556
|
) : null,
|
|
4660
|
-
content.length > 0 ? /* @__PURE__ */
|
|
4661
|
-
/* @__PURE__ */
|
|
4662
|
-
/* @__PURE__ */
|
|
5557
|
+
content.length > 0 ? /* @__PURE__ */ jsxs24("section", { class: `${p25}-home-content`, children: [
|
|
5558
|
+
/* @__PURE__ */ jsx30("div", { class: `${p25}-home-content-title`, children: contentTitle }),
|
|
5559
|
+
/* @__PURE__ */ jsx30("div", { class: `${p25}-home-content-list`, children: content.map((item) => /* @__PURE__ */ jsx30(
|
|
4663
5560
|
ListRow,
|
|
4664
5561
|
{
|
|
4665
5562
|
title: item.title,
|
|
@@ -4675,20 +5572,20 @@ function HomeRoot(props2) {
|
|
|
4675
5572
|
}
|
|
4676
5573
|
var homeLayout = {
|
|
4677
5574
|
Icon: HomeIcon,
|
|
4678
|
-
Root: (props2) => /* @__PURE__ */
|
|
5575
|
+
Root: (props2) => /* @__PURE__ */ jsx30(HomeRoot, { ...props2 })
|
|
4679
5576
|
};
|
|
4680
5577
|
|
|
4681
5578
|
// src/ui/modules/news.tsx
|
|
4682
|
-
import { useEffect as useEffect13, useState as
|
|
4683
|
-
import { jsx as
|
|
4684
|
-
var
|
|
5579
|
+
import { useEffect as useEffect13, useState as useState10 } from "preact/hooks";
|
|
5580
|
+
import { jsx as jsx31, jsxs as jsxs25 } from "preact/jsx-runtime";
|
|
5581
|
+
var p26 = BRAND.cssPrefix;
|
|
4685
5582
|
var log14 = logger.scope("news");
|
|
4686
5583
|
function NewsRoot({ transport, strings, config, nav, panelProps }) {
|
|
4687
5584
|
const tags = config.contentTags;
|
|
4688
|
-
const [state, setState] =
|
|
4689
|
-
const [errorMsg, setErrorMsg] =
|
|
4690
|
-
const [items, setItems] =
|
|
4691
|
-
const [reloadKey, setReloadKey] =
|
|
5585
|
+
const [state, setState] = useState10("loading");
|
|
5586
|
+
const [errorMsg, setErrorMsg] = useState10(strings.errorGeneric);
|
|
5587
|
+
const [items, setItems] = useState10([]);
|
|
5588
|
+
const [reloadKey, setReloadKey] = useState10(0);
|
|
4692
5589
|
useEffect13(() => {
|
|
4693
5590
|
let cancelled = false;
|
|
4694
5591
|
setState("loading");
|
|
@@ -4707,38 +5604,38 @@ function NewsRoot({ transport, strings, config, nav, panelProps }) {
|
|
|
4707
5604
|
};
|
|
4708
5605
|
}, [transport, tags, reloadKey]);
|
|
4709
5606
|
function renderBody() {
|
|
4710
|
-
if (state === "loading") return /* @__PURE__ */
|
|
5607
|
+
if (state === "loading") return /* @__PURE__ */ jsx31(ModuleState, { message: strings.newsLoading, strings });
|
|
4711
5608
|
if (state === "error") {
|
|
4712
|
-
return /* @__PURE__ */
|
|
5609
|
+
return /* @__PURE__ */ jsx31(ModuleState, { tone: "error", message: errorMsg, onRetry: () => setReloadKey((k) => k + 1), strings });
|
|
4713
5610
|
}
|
|
4714
|
-
if (items.length === 0) return /* @__PURE__ */
|
|
4715
|
-
return /* @__PURE__ */
|
|
5611
|
+
if (items.length === 0) return /* @__PURE__ */ jsx31(ModuleState, { message: strings.newsEmpty, strings });
|
|
5612
|
+
return /* @__PURE__ */ jsx31("div", { class: `${p26}-news-list`, children: items.map((item) => /* @__PURE__ */ jsxs25(
|
|
4716
5613
|
"button",
|
|
4717
5614
|
{
|
|
4718
5615
|
type: "button",
|
|
4719
|
-
class: `${
|
|
5616
|
+
class: `${p26}-news-card`,
|
|
4720
5617
|
onClick: () => nav.push({ kind: "content", id: item.id, title: item.title }),
|
|
4721
5618
|
"data-testid": tid(TID.newsItem, item.id),
|
|
4722
5619
|
children: [
|
|
4723
|
-
item.image ? /* @__PURE__ */
|
|
4724
|
-
/* @__PURE__ */
|
|
4725
|
-
item.tags && item.tags.length > 0 ? /* @__PURE__ */
|
|
4726
|
-
/* @__PURE__ */
|
|
4727
|
-
item.description ? /* @__PURE__ */
|
|
5620
|
+
item.image ? /* @__PURE__ */ jsx31("img", { class: `${p26}-news-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
|
|
5621
|
+
/* @__PURE__ */ jsxs25("span", { class: `${p26}-news-body`, children: [
|
|
5622
|
+
item.tags && item.tags.length > 0 ? /* @__PURE__ */ jsx31("span", { class: `${p26}-news-tags`, children: item.tags.map((t) => /* @__PURE__ */ jsx31("span", { class: `${p26}-news-tag`, children: t }, t)) }) : null,
|
|
5623
|
+
/* @__PURE__ */ jsx31("span", { class: `${p26}-news-title`, children: item.title }),
|
|
5624
|
+
item.description ? /* @__PURE__ */ jsx31("span", { class: `${p26}-news-summary`, children: item.description }) : null
|
|
4728
5625
|
] })
|
|
4729
5626
|
]
|
|
4730
5627
|
},
|
|
4731
5628
|
item.id
|
|
4732
5629
|
)) });
|
|
4733
5630
|
}
|
|
4734
|
-
return /* @__PURE__ */
|
|
4735
|
-
/* @__PURE__ */
|
|
4736
|
-
/* @__PURE__ */
|
|
5631
|
+
return /* @__PURE__ */ jsxs25("div", { class: `${p26}-module`, children: [
|
|
5632
|
+
/* @__PURE__ */ jsx31(TitleBar, { title: strings.newsTitle, actions: /* @__PURE__ */ jsx31(HeaderActions, { panelProps, variant: "plain" }) }),
|
|
5633
|
+
/* @__PURE__ */ jsx31("div", { class: `${p26}-module-scroll`, children: renderBody() })
|
|
4737
5634
|
] });
|
|
4738
5635
|
}
|
|
4739
5636
|
var newsLayout = {
|
|
4740
5637
|
Icon: NewsIcon,
|
|
4741
|
-
Root: (props2) => /* @__PURE__ */
|
|
5638
|
+
Root: (props2) => /* @__PURE__ */ jsx31(NewsRoot, { ...props2 })
|
|
4742
5639
|
};
|
|
4743
5640
|
|
|
4744
5641
|
// src/ui/modules/registry.ts
|
|
@@ -4750,28 +5647,28 @@ var LAYOUTS = {
|
|
|
4750
5647
|
};
|
|
4751
5648
|
|
|
4752
5649
|
// src/ui/home-tab-bar.tsx
|
|
4753
|
-
import { jsx as
|
|
4754
|
-
var
|
|
5650
|
+
import { jsx as jsx32, jsxs as jsxs26 } from "preact/jsx-runtime";
|
|
5651
|
+
var p27 = BRAND.cssPrefix;
|
|
4755
5652
|
function HomeTabBar({ modules, activeTab, strings, unreadCount, onSelect }) {
|
|
4756
|
-
return /* @__PURE__ */
|
|
5653
|
+
return /* @__PURE__ */ jsx32("nav", { class: `${p27}-tabbar`, role: "tablist", "aria-label": strings.panelTitle, children: modules.map((m) => {
|
|
4757
5654
|
const Icon = LAYOUTS[m.layout].Icon;
|
|
4758
5655
|
const selected = m.id === activeTab;
|
|
4759
5656
|
const badge = m.layout === "chat" && unreadCount > 0 ? unreadCount > 9 ? "9+" : String(unreadCount) : null;
|
|
4760
|
-
return /* @__PURE__ */
|
|
5657
|
+
return /* @__PURE__ */ jsxs26(
|
|
4761
5658
|
"button",
|
|
4762
5659
|
{
|
|
4763
5660
|
type: "button",
|
|
4764
5661
|
role: "tab",
|
|
4765
5662
|
"aria-selected": selected,
|
|
4766
|
-
class: `${
|
|
5663
|
+
class: `${p27}-tab`,
|
|
4767
5664
|
onClick: () => onSelect(m.id),
|
|
4768
5665
|
"data-testid": tid(TID.tab, m.id),
|
|
4769
5666
|
children: [
|
|
4770
|
-
/* @__PURE__ */
|
|
4771
|
-
/* @__PURE__ */
|
|
4772
|
-
badge ? /* @__PURE__ */
|
|
5667
|
+
/* @__PURE__ */ jsxs26("span", { class: `${p27}-tab-icon`, "aria-hidden": "true", children: [
|
|
5668
|
+
/* @__PURE__ */ jsx32(Icon, {}),
|
|
5669
|
+
badge ? /* @__PURE__ */ jsx32("span", { class: `${p27}-tab-badge`, "data-testid": TID.tabBadge, children: badge }) : null
|
|
4773
5670
|
] }),
|
|
4774
|
-
/* @__PURE__ */
|
|
5671
|
+
/* @__PURE__ */ jsx32("span", { class: `${p27}-tab-label`, children: moduleLabel(strings, m.label) })
|
|
4775
5672
|
]
|
|
4776
5673
|
},
|
|
4777
5674
|
m.id
|
|
@@ -4780,12 +5677,12 @@ function HomeTabBar({ modules, activeTab, strings, unreadCount, onSelect }) {
|
|
|
4780
5677
|
}
|
|
4781
5678
|
|
|
4782
5679
|
// src/ui/iframe-view.tsx
|
|
4783
|
-
import { jsx as
|
|
4784
|
-
var
|
|
5680
|
+
import { jsx as jsx33, jsxs as jsxs27 } from "preact/jsx-runtime";
|
|
5681
|
+
var p28 = BRAND.cssPrefix;
|
|
4785
5682
|
var SANDBOX = "allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads";
|
|
4786
5683
|
function IframeView({ url, title, strings, onBack, actions }) {
|
|
4787
|
-
return /* @__PURE__ */
|
|
4788
|
-
/* @__PURE__ */
|
|
5684
|
+
return /* @__PURE__ */ jsxs27("div", { class: `${p28}-module`, children: [
|
|
5685
|
+
/* @__PURE__ */ jsx33(
|
|
4789
5686
|
BackHeader,
|
|
4790
5687
|
{
|
|
4791
5688
|
title: title || strings.moduleBack,
|
|
@@ -4794,10 +5691,10 @@ function IframeView({ url, title, strings, onBack, actions }) {
|
|
|
4794
5691
|
actions
|
|
4795
5692
|
}
|
|
4796
5693
|
),
|
|
4797
|
-
/* @__PURE__ */
|
|
5694
|
+
/* @__PURE__ */ jsx33(
|
|
4798
5695
|
"iframe",
|
|
4799
5696
|
{
|
|
4800
|
-
class: `${
|
|
5697
|
+
class: `${p28}-content-frame`,
|
|
4801
5698
|
src: url,
|
|
4802
5699
|
title: title || "content",
|
|
4803
5700
|
sandbox: SANDBOX,
|
|
@@ -4810,14 +5707,14 @@ function IframeView({ url, title, strings, onBack, actions }) {
|
|
|
4810
5707
|
}
|
|
4811
5708
|
|
|
4812
5709
|
// src/ui/content-view.tsx
|
|
4813
|
-
import { useCallback as useCallback3, useEffect as useEffect14, useState as
|
|
4814
|
-
import { jsx as
|
|
4815
|
-
var
|
|
5710
|
+
import { useCallback as useCallback3, useEffect as useEffect14, useState as useState11 } from "preact/hooks";
|
|
5711
|
+
import { jsx as jsx34, jsxs as jsxs28 } from "preact/jsx-runtime";
|
|
5712
|
+
var p29 = BRAND.cssPrefix;
|
|
4816
5713
|
var log15 = logger.scope("content");
|
|
4817
5714
|
function ContentView({ id, title, transport, strings, onBack, actions }) {
|
|
4818
|
-
const [item, setItem] =
|
|
4819
|
-
const [failed, setFailed] =
|
|
4820
|
-
const [reloadKey, setReloadKey] =
|
|
5715
|
+
const [item, setItem] = useState11(null);
|
|
5716
|
+
const [failed, setFailed] = useState11(false);
|
|
5717
|
+
const [reloadKey, setReloadKey] = useState11(0);
|
|
4821
5718
|
const retry = useCallback3(() => {
|
|
4822
5719
|
setFailed(false);
|
|
4823
5720
|
setItem(null);
|
|
@@ -4840,17 +5737,17 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
|
|
|
4840
5737
|
};
|
|
4841
5738
|
}, [transport, id, reloadKey]);
|
|
4842
5739
|
function renderBody() {
|
|
4843
|
-
if (failed) return /* @__PURE__ */
|
|
4844
|
-
if (item === null) return /* @__PURE__ */
|
|
4845
|
-
return /* @__PURE__ */
|
|
4846
|
-
item.image ? /* @__PURE__ */
|
|
4847
|
-
item.description ? /* @__PURE__ */
|
|
4848
|
-
item.tags && item.tags.length > 0 ? /* @__PURE__ */
|
|
4849
|
-
/* @__PURE__ */
|
|
5740
|
+
if (failed) return /* @__PURE__ */ jsx34(ModuleState, { tone: "error", message: strings.errorGeneric, onRetry: retry, strings });
|
|
5741
|
+
if (item === null) return /* @__PURE__ */ jsx34(ModuleState, { message: strings.contentLoading, strings });
|
|
5742
|
+
return /* @__PURE__ */ jsxs28("article", { class: `${p29}-content`, "data-testid": TID.contentView, children: [
|
|
5743
|
+
item.image ? /* @__PURE__ */ jsx34("img", { class: `${p29}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
|
|
5744
|
+
item.description ? /* @__PURE__ */ jsx34("p", { class: `${p29}-content-subtitle`, children: item.description }) : null,
|
|
5745
|
+
item.tags && item.tags.length > 0 ? /* @__PURE__ */ jsx34("span", { class: `${p29}-news-tags`, children: item.tags.map((t) => /* @__PURE__ */ jsx34("span", { class: `${p29}-news-tag`, children: t }, t)) }) : null,
|
|
5746
|
+
/* @__PURE__ */ jsx34(StaticMarkdown, { text: item.content ?? "" })
|
|
4850
5747
|
] });
|
|
4851
5748
|
}
|
|
4852
|
-
return /* @__PURE__ */
|
|
4853
|
-
/* @__PURE__ */
|
|
5749
|
+
return /* @__PURE__ */ jsxs28("div", { class: `${p29}-module`, children: [
|
|
5750
|
+
/* @__PURE__ */ jsx34(
|
|
4854
5751
|
BackHeader,
|
|
4855
5752
|
{
|
|
4856
5753
|
title: item?.title || title || strings.moduleBack,
|
|
@@ -4860,13 +5757,13 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
|
|
|
4860
5757
|
testid: TID.backHeader
|
|
4861
5758
|
}
|
|
4862
5759
|
),
|
|
4863
|
-
/* @__PURE__ */
|
|
5760
|
+
/* @__PURE__ */ jsx34("div", { class: `${p29}-module-scroll`, "data-testid": TID.contentScroll, children: renderBody() })
|
|
4864
5761
|
] });
|
|
4865
5762
|
}
|
|
4866
5763
|
|
|
4867
5764
|
// src/ui/messenger-home.tsx
|
|
4868
|
-
import { jsx as
|
|
4869
|
-
var
|
|
5765
|
+
import { jsx as jsx35, jsxs as jsxs29 } from "preact/jsx-runtime";
|
|
5766
|
+
var p30 = BRAND.cssPrefix;
|
|
4870
5767
|
function MessengerHome({
|
|
4871
5768
|
panelProps,
|
|
4872
5769
|
enabledModules,
|
|
@@ -4898,7 +5795,7 @@ function MessengerHome({
|
|
|
4898
5795
|
}, []);
|
|
4899
5796
|
const { visible: dragOver } = useFileDrop({ containerRef, onDrop: onDropItems });
|
|
4900
5797
|
useDragMove(containerRef.current, options.mode === "modal");
|
|
4901
|
-
const navState =
|
|
5798
|
+
const navState = useComputed6(() => nav.sig.value).value;
|
|
4902
5799
|
const top = topScreen(navState);
|
|
4903
5800
|
const activeModule = options.modules.byId[navState.activeTab];
|
|
4904
5801
|
const isReader = top?.kind === "iframe" || top?.kind === "content";
|
|
@@ -4934,12 +5831,12 @@ function MessengerHome({
|
|
|
4934
5831
|
nav: moduleNav,
|
|
4935
5832
|
panelProps
|
|
4936
5833
|
});
|
|
4937
|
-
const plainActions = /* @__PURE__ */
|
|
5834
|
+
const plainActions = /* @__PURE__ */ jsx35(HeaderActions, { panelProps, variant: "plain" });
|
|
4938
5835
|
let body;
|
|
4939
5836
|
if (top?.kind === "iframe") {
|
|
4940
|
-
body = /* @__PURE__ */
|
|
5837
|
+
body = /* @__PURE__ */ jsx35(IframeView, { url: top.url, title: top.title, strings, onBack: nav.pop, actions: plainActions });
|
|
4941
5838
|
} else if (top?.kind === "content") {
|
|
4942
|
-
body = /* @__PURE__ */
|
|
5839
|
+
body = /* @__PURE__ */ jsx35(
|
|
4943
5840
|
ContentView,
|
|
4944
5841
|
{
|
|
4945
5842
|
id: top.id,
|
|
@@ -4951,7 +5848,7 @@ function MessengerHome({
|
|
|
4951
5848
|
}
|
|
4952
5849
|
);
|
|
4953
5850
|
} else if (activeModule?.layout === "chat") {
|
|
4954
|
-
body = /* @__PURE__ */
|
|
5851
|
+
body = /* @__PURE__ */ jsx35(
|
|
4955
5852
|
PanelContent,
|
|
4956
5853
|
{
|
|
4957
5854
|
...panelProps,
|
|
@@ -4962,23 +5859,23 @@ function MessengerHome({
|
|
|
4962
5859
|
);
|
|
4963
5860
|
} else if (activeModule) {
|
|
4964
5861
|
const Root = LAYOUTS[activeModule.layout].Root;
|
|
4965
|
-
body = Root ? /* @__PURE__ */
|
|
5862
|
+
body = Root ? /* @__PURE__ */ jsx35(Root, { ...screenProps(activeModule) }, activeModule.id) : null;
|
|
4966
5863
|
} else {
|
|
4967
5864
|
body = null;
|
|
4968
5865
|
}
|
|
4969
|
-
return /* @__PURE__ */
|
|
5866
|
+
return /* @__PURE__ */ jsxs29(
|
|
4970
5867
|
"div",
|
|
4971
5868
|
{
|
|
4972
5869
|
ref: containerRef,
|
|
4973
|
-
class: `${
|
|
5870
|
+
class: `${p30}-panel ${p30}-messenger`,
|
|
4974
5871
|
role: "dialog",
|
|
4975
5872
|
"aria-modal": "false",
|
|
4976
5873
|
"aria-label": strings.panelTitle,
|
|
4977
5874
|
style: { position: "relative" },
|
|
4978
5875
|
"data-testid": TID.messengerHome,
|
|
4979
5876
|
children: [
|
|
4980
|
-
/* @__PURE__ */
|
|
4981
|
-
showTabBar ? /* @__PURE__ */
|
|
5877
|
+
/* @__PURE__ */ jsx35("div", { class: `${p30}-messenger-body`, children: body }),
|
|
5878
|
+
showTabBar ? /* @__PURE__ */ jsx35(
|
|
4982
5879
|
HomeTabBar,
|
|
4983
5880
|
{
|
|
4984
5881
|
modules: enabledModules,
|
|
@@ -4988,8 +5885,8 @@ function MessengerHome({
|
|
|
4988
5885
|
onSelect: nav.switchTab
|
|
4989
5886
|
}
|
|
4990
5887
|
) : null,
|
|
4991
|
-
/* @__PURE__ */
|
|
4992
|
-
options.size.resize?.enabled && !(activeModule?.layout === "chat" && !top) ? /* @__PURE__ */
|
|
5888
|
+
/* @__PURE__ */ jsx35(PoweredByBar, { poweredBy: options.poweredBy }),
|
|
5889
|
+
options.size.resize?.enabled && !(activeModule?.layout === "chat" && !top) ? /* @__PURE__ */ jsx35(
|
|
4993
5890
|
ResizeGrip,
|
|
4994
5891
|
{
|
|
4995
5892
|
panelEl: containerRef.current,
|
|
@@ -5006,29 +5903,29 @@ function MessengerHome({
|
|
|
5006
5903
|
}
|
|
5007
5904
|
|
|
5008
5905
|
// src/ui/modules-empty.tsx
|
|
5009
|
-
import { jsx as
|
|
5010
|
-
var
|
|
5906
|
+
import { jsx as jsx36, jsxs as jsxs30 } from "preact/jsx-runtime";
|
|
5907
|
+
var p31 = BRAND.cssPrefix;
|
|
5011
5908
|
function ModulesEmpty({ strings, onClose }) {
|
|
5012
|
-
return /* @__PURE__ */
|
|
5909
|
+
return /* @__PURE__ */ jsxs30(
|
|
5013
5910
|
"div",
|
|
5014
5911
|
{
|
|
5015
|
-
class: `${
|
|
5912
|
+
class: `${p31}-panel ${p31}-modules-empty`,
|
|
5016
5913
|
role: "dialog",
|
|
5017
5914
|
"aria-label": strings.panelTitle,
|
|
5018
5915
|
"data-testid": TID.modulesEmpty,
|
|
5019
5916
|
children: [
|
|
5020
|
-
onClose ? /* @__PURE__ */
|
|
5917
|
+
onClose ? /* @__PURE__ */ jsx36(
|
|
5021
5918
|
"button",
|
|
5022
5919
|
{
|
|
5023
5920
|
type: "button",
|
|
5024
|
-
class: `${
|
|
5921
|
+
class: `${p31}-icon-btn ${p31}-modules-empty-close`,
|
|
5025
5922
|
onClick: onClose,
|
|
5026
5923
|
"aria-label": strings.close,
|
|
5027
5924
|
title: strings.close,
|
|
5028
|
-
children: /* @__PURE__ */
|
|
5925
|
+
children: /* @__PURE__ */ jsx36(CloseIcon, {})
|
|
5029
5926
|
}
|
|
5030
5927
|
) : null,
|
|
5031
|
-
/* @__PURE__ */
|
|
5928
|
+
/* @__PURE__ */ jsx36("p", { class: `${p31}-modules-empty-text`, children: strings.modulesEmpty })
|
|
5032
5929
|
]
|
|
5033
5930
|
}
|
|
5034
5931
|
);
|
|
@@ -5083,11 +5980,11 @@ function animateTypewriter(msg, text, charsPerSecond, abort) {
|
|
|
5083
5980
|
}
|
|
5084
5981
|
|
|
5085
5982
|
// src/ui/use-launcher-callout.ts
|
|
5086
|
-
import { useCallback as useCallback5, useEffect as useEffect16, useState as
|
|
5983
|
+
import { useCallback as useCallback5, useEffect as useEffect16, useState as useState12 } from "preact/hooks";
|
|
5087
5984
|
function useLauncherCallout({ callout, persistence }) {
|
|
5088
5985
|
const textKey = callout?.text ?? "";
|
|
5089
5986
|
const persistent = callout?.persistent ?? true;
|
|
5090
|
-
const [dismissed, setDismissed] =
|
|
5987
|
+
const [dismissed, setDismissed] = useState12(() => persistent ? false : persistence.loadCalloutDismissed(textKey));
|
|
5091
5988
|
useEffect16(() => {
|
|
5092
5989
|
setDismissed(persistent ? false : persistence.loadCalloutDismissed(textKey));
|
|
5093
5990
|
}, [textKey, persistent, persistence]);
|
|
@@ -5099,21 +5996,21 @@ function useLauncherCallout({ callout, persistence }) {
|
|
|
5099
5996
|
}
|
|
5100
5997
|
|
|
5101
5998
|
// src/ui/app.tsx
|
|
5102
|
-
import { jsx as
|
|
5999
|
+
import { jsx as jsx37, jsxs as jsxs31 } from "preact/jsx-runtime";
|
|
5103
6000
|
var log16 = logger.scope("app");
|
|
5104
|
-
var
|
|
6001
|
+
var p32 = BRAND.cssPrefix;
|
|
5105
6002
|
function App({ options, hostElement, bus }) {
|
|
5106
|
-
const [persistence] =
|
|
5107
|
-
const [visitorId, setVisitorId] =
|
|
6003
|
+
const [persistence] = useState13(() => createPersistence(options.widgetId, options.storage));
|
|
6004
|
+
const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
|
|
5108
6005
|
const initialSettings = persistence.loadUserPrefs();
|
|
5109
|
-
const [activeLocale, setActiveLocale] =
|
|
5110
|
-
const [activeThemeMode, setActiveThemeMode] =
|
|
6006
|
+
const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
|
|
6007
|
+
const [activeThemeMode, setActiveThemeMode] = useState13(
|
|
5111
6008
|
() => initialSettings.themeMode ?? options.themeMode
|
|
5112
6009
|
);
|
|
5113
|
-
const sessionIdSig =
|
|
5114
|
-
const messagesSig =
|
|
5115
|
-
const unreadCountSig =
|
|
5116
|
-
const [loadingMessages, setLoadingMessages] =
|
|
6010
|
+
const sessionIdSig = useSignal2(persistence.loadSessionId());
|
|
6011
|
+
const messagesSig = useSignal2([]);
|
|
6012
|
+
const unreadCountSig = useSignal2(0);
|
|
6013
|
+
const [loadingMessages, setLoadingMessages] = useState13(false);
|
|
5117
6014
|
function landingTab() {
|
|
5118
6015
|
const list = options.modules.list;
|
|
5119
6016
|
const ids = new Set(list.map((m) => m.id));
|
|
@@ -5132,14 +6029,14 @@ function App({ options, hostElement, bus }) {
|
|
|
5132
6029
|
const homeNav = homeNavRef.current;
|
|
5133
6030
|
const chatTabIdRef = useRef8(void 0);
|
|
5134
6031
|
chatTabIdRef.current = chatTabId();
|
|
5135
|
-
const [sessionReady, setSessionReady] =
|
|
6032
|
+
const [sessionReady, setSessionReady] = useState13(false);
|
|
5136
6033
|
const isInlineLike = options.mode === "standalone" || options.mode === "inline";
|
|
5137
6034
|
const initialPanelRef = useRef8(
|
|
5138
6035
|
resolveInitialPanelState(options, currentViewportWidth(), persistence.loadPanelOpen(), persistence.loadPanelSize())
|
|
5139
6036
|
);
|
|
5140
|
-
const [isOpen, setIsOpen] =
|
|
6037
|
+
const [isOpen, setIsOpen] = useState13(initialPanelRef.current.panelOpen);
|
|
5141
6038
|
const initialPanelApplied = useRef8(false);
|
|
5142
|
-
const [launcherLeaving, setLauncherLeaving] =
|
|
6039
|
+
const [launcherLeaving, setLauncherLeaving] = useState13(false);
|
|
5143
6040
|
const { dismissed: calloutDismissed, dismissCallout: dismissCalloutRaw } = useLauncherCallout({
|
|
5144
6041
|
callout: options.launcher.callout,
|
|
5145
6042
|
persistence
|
|
@@ -5150,19 +6047,20 @@ function App({ options, hostElement, bus }) {
|
|
|
5150
6047
|
bus.emit("calloutDismiss", void 0);
|
|
5151
6048
|
dismissCalloutRaw();
|
|
5152
6049
|
}, [bus, dismissCalloutRaw]);
|
|
5153
|
-
const [panelSize, setPanelSize] =
|
|
6050
|
+
const [panelSize, setPanelSize] = useState13(initialPanelRef.current.panelSize);
|
|
5154
6051
|
const initialSizeApplied = useRef8(false);
|
|
5155
|
-
const [view, setView] =
|
|
5156
|
-
const [canSend, setCanSend] =
|
|
5157
|
-
const [streaming, setStreaming] =
|
|
5158
|
-
const [agent, setAgent] =
|
|
5159
|
-
const [suggestions, setSuggestions] =
|
|
5160
|
-
const [activeCancel, setActiveCancel] =
|
|
6052
|
+
const [view, setView] = useState13("chat");
|
|
6053
|
+
const [canSend, setCanSend] = useState13(true);
|
|
6054
|
+
const [streaming, setStreaming] = useState13(false);
|
|
6055
|
+
const [agent, setAgent] = useState13(null);
|
|
6056
|
+
const [suggestions, setSuggestions] = useState13([]);
|
|
6057
|
+
const [activeCancel, setActiveCancel] = useState13(null);
|
|
5161
6058
|
const welcomeAbortRef = useRef8(null);
|
|
5162
|
-
const [parsedSite, setParsedSite] =
|
|
5163
|
-
const [parsedBlocks, setParsedBlocks] =
|
|
5164
|
-
const [sidebarCollapsed, setSidebarCollapsed] =
|
|
5165
|
-
const [
|
|
6059
|
+
const [parsedSite, setParsedSite] = useState13(void 0);
|
|
6060
|
+
const [parsedBlocks, setParsedBlocks] = useState13(void 0);
|
|
6061
|
+
const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
|
|
6062
|
+
const [intakeValues, setIntakeValues] = useState13(() => persistence.loadIntake());
|
|
6063
|
+
const [transport] = useState13(
|
|
5166
6064
|
() => new AgentTransport({
|
|
5167
6065
|
baseUrl: options.baseUrl,
|
|
5168
6066
|
auth: createAuth({
|
|
@@ -5173,8 +6071,8 @@ function App({ options, hostElement, bus }) {
|
|
|
5173
6071
|
endpoints: options.endpoints
|
|
5174
6072
|
})
|
|
5175
6073
|
);
|
|
5176
|
-
const [reducer] =
|
|
5177
|
-
const [feedback] =
|
|
6074
|
+
const [reducer] = useState13(() => new StreamReducer(messagesSig));
|
|
6075
|
+
const [feedback] = useState13(() => new FeedbackBus(options.sound, options.haptics));
|
|
5178
6076
|
const patchAndSync = useCallback6(
|
|
5179
6077
|
(patch) => {
|
|
5180
6078
|
persistence.patchUserPrefs(patch);
|
|
@@ -5344,9 +6242,11 @@ function App({ options, hostElement, bus }) {
|
|
|
5344
6242
|
);
|
|
5345
6243
|
const userSig = JSON.stringify(options.userContext ?? null);
|
|
5346
6244
|
const pageSig = JSON.stringify(options.pageContext ?? null);
|
|
6245
|
+
const intakeSig = JSON.stringify(intakeValues ?? null);
|
|
5347
6246
|
useEffect17(() => {
|
|
5348
|
-
|
|
5349
|
-
|
|
6247
|
+
const merged = intakeValues ? { ...intakeValues, ...options.userContext } : options.userContext;
|
|
6248
|
+
transport.setContext(merged, toWirePageContext(options.pageContext));
|
|
6249
|
+
}, [transport, userSig, pageSig, intakeSig]);
|
|
5350
6250
|
const runResume = useCallback6(
|
|
5351
6251
|
async (handle) => {
|
|
5352
6252
|
let bubble = null;
|
|
@@ -5434,24 +6334,8 @@ function App({ options, hostElement, bus }) {
|
|
|
5434
6334
|
document.addEventListener("keydown", onKey);
|
|
5435
6335
|
return () => document.removeEventListener("keydown", onKey);
|
|
5436
6336
|
}, [isOpen, options.mode]);
|
|
5437
|
-
const
|
|
5438
|
-
async (
|
|
5439
|
-
log16.info("send", { textLen: text.length, attachments: attachments.length, streaming });
|
|
5440
|
-
if (streaming) return;
|
|
5441
|
-
bus.emit("send", { text, attachmentCount: attachments.length });
|
|
5442
|
-
if (suggestions.length > 0) setSuggestions([]);
|
|
5443
|
-
const uploaded = await uploadAttachments(transport, attachments, (err) => {
|
|
5444
|
-
log16.warn("upload failed", { err });
|
|
5445
|
-
bus.emit("error", err);
|
|
5446
|
-
options.onError?.(err);
|
|
5447
|
-
});
|
|
5448
|
-
feedback.unlock();
|
|
5449
|
-
feedback.play("messageSent");
|
|
5450
|
-
const userMsg = makeUserMessage(text, uploaded);
|
|
5451
|
-
const assistantMsg = makeAssistantMessage();
|
|
5452
|
-
messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
|
|
5453
|
-
reducer.attach(assistantMsg);
|
|
5454
|
-
emitMessage(bus, options, "user", text);
|
|
6337
|
+
const streamAssistant = useCallback6(
|
|
6338
|
+
async (assistantMsg, trigger) => {
|
|
5455
6339
|
const activeSessionId = sessionIdSig.value ?? uuid7();
|
|
5456
6340
|
if (!sessionIdSig.value) {
|
|
5457
6341
|
sessionIdSig.value = activeSessionId;
|
|
@@ -5460,10 +6344,10 @@ function App({ options, hostElement, bus }) {
|
|
|
5460
6344
|
const body = buildSendMessageRequest({
|
|
5461
6345
|
messages: messagesSig.value.slice(0, -1).map(fromReactive),
|
|
5462
6346
|
sessionId: activeSessionId,
|
|
5463
|
-
// textModel + imageModel are backend-only — selected per
|
|
5464
|
-
// deployment in the dashboard, never passed up by the widget.
|
|
6347
|
+
// textModel + imageModel are backend-only — selected per deployment.
|
|
5465
6348
|
tools: options.features.tools,
|
|
5466
6349
|
responseMode: options.responseMode,
|
|
6350
|
+
trigger,
|
|
5467
6351
|
// Identity + preferences ride on every message — server may need
|
|
5468
6352
|
// them to route, persist, or reconcile in-flight.
|
|
5469
6353
|
visitorId,
|
|
@@ -5495,19 +6379,95 @@ function App({ options, hostElement, bus }) {
|
|
|
5495
6379
|
messagesSig.value = [...messagesSig.value];
|
|
5496
6380
|
}
|
|
5497
6381
|
},
|
|
5498
|
-
[
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
6382
|
+
[transport, reducer, messagesSig, sessionIdSig, options, bus, feedback, persistence, visitorId]
|
|
6383
|
+
);
|
|
6384
|
+
const resolveTool = useCallback6(
|
|
6385
|
+
(toolCallId, trigger, mutate) => {
|
|
6386
|
+
if (streaming) return;
|
|
6387
|
+
const last = messagesSig.value.at(-1);
|
|
6388
|
+
const part = last?.partsSig.value.find(
|
|
6389
|
+
(pt) => pt.kind === "tool" && pt.toolCallId === toolCallId
|
|
6390
|
+
);
|
|
6391
|
+
if (!part) {
|
|
6392
|
+
log16.warn("resolveTool: tool part not found", { toolCallId });
|
|
6393
|
+
return;
|
|
6394
|
+
}
|
|
6395
|
+
mutate(part);
|
|
6396
|
+
if (last) last.partsSig.value = [...last.partsSig.value];
|
|
6397
|
+
const assistantMsg = makeAssistantMessage();
|
|
6398
|
+
messagesSig.value = [...messagesSig.value, assistantMsg];
|
|
6399
|
+
reducer.attach(assistantMsg);
|
|
6400
|
+
void streamAssistant(assistantMsg, trigger);
|
|
6401
|
+
},
|
|
6402
|
+
[streaming, messagesSig, reducer, streamAssistant]
|
|
6403
|
+
);
|
|
6404
|
+
const handleToolResult = useCallback6(
|
|
6405
|
+
(toolCallId, output) => {
|
|
6406
|
+
log16.info("toolResult", { toolCallId });
|
|
6407
|
+
bus.emit("toolResult", { toolCallId });
|
|
6408
|
+
resolveTool(toolCallId, TRIGGER.toolResult, (part) => {
|
|
6409
|
+
part.outputSig.value = output;
|
|
6410
|
+
part.stateSig.value = "output";
|
|
6411
|
+
});
|
|
6412
|
+
},
|
|
6413
|
+
[bus, resolveTool]
|
|
6414
|
+
);
|
|
6415
|
+
const handleToolDecision = useCallback6(
|
|
6416
|
+
(toolCallId, approved, reason) => {
|
|
6417
|
+
log16.info("toolDecision", { toolCallId, approved });
|
|
6418
|
+
bus.emit("toolDecision", { toolCallId, approved });
|
|
6419
|
+
resolveTool(toolCallId, TRIGGER.toolApproval, (part) => {
|
|
6420
|
+
const id = part.approvalSig.value?.id ?? toolCallId;
|
|
6421
|
+
part.approvalSig.value = { id, approved, reason };
|
|
6422
|
+
part.stateSig.value = "output";
|
|
6423
|
+
});
|
|
6424
|
+
},
|
|
6425
|
+
[bus, resolveTool]
|
|
6426
|
+
);
|
|
6427
|
+
const toolInteraction = useMemo3(
|
|
6428
|
+
() => ({ humanInLoop: options.features.humanInLoop, onResult: handleToolResult, onDecision: handleToolDecision }),
|
|
6429
|
+
[options.features.humanInLoop, handleToolResult, handleToolDecision]
|
|
6430
|
+
);
|
|
6431
|
+
const intakePending = options.intake.enabled && intakeValues === null;
|
|
6432
|
+
const handleIntakeComplete = useCallback6(
|
|
6433
|
+
(values) => {
|
|
6434
|
+
const hasValues = Object.keys(values).length > 0;
|
|
6435
|
+
log16.info("intakeComplete", { fields: Object.keys(values).length, skipped: !hasValues });
|
|
6436
|
+
persistence.saveIntake(values);
|
|
6437
|
+
setIntakeValues(values);
|
|
6438
|
+
bus.emit("intakeSubmit", values);
|
|
6439
|
+
if (!hasValues) return;
|
|
6440
|
+
const activeSessionId = sessionIdSig.value ?? uuid7();
|
|
6441
|
+
if (!sessionIdSig.value) {
|
|
6442
|
+
sessionIdSig.value = activeSessionId;
|
|
6443
|
+
persistence.saveSessionId(activeSessionId);
|
|
6444
|
+
transport.primeIdentity(void 0, activeSessionId);
|
|
6445
|
+
}
|
|
6446
|
+
void transport.submitIntake(activeSessionId, values);
|
|
6447
|
+
},
|
|
6448
|
+
[persistence, bus, sessionIdSig, transport]
|
|
6449
|
+
);
|
|
6450
|
+
const handleSend = useCallback6(
|
|
6451
|
+
async (text, attachments) => {
|
|
6452
|
+
log16.info("send", { textLen: text.length, attachments: attachments.length, streaming });
|
|
6453
|
+
if (streaming) return;
|
|
6454
|
+
bus.emit("send", { text, attachmentCount: attachments.length });
|
|
6455
|
+
if (suggestions.length > 0) setSuggestions([]);
|
|
6456
|
+
const uploaded = await uploadAttachments(transport, attachments, (err) => {
|
|
6457
|
+
log16.warn("upload failed", { err });
|
|
6458
|
+
bus.emit("error", err);
|
|
6459
|
+
options.onError?.(err);
|
|
6460
|
+
});
|
|
6461
|
+
feedback.unlock();
|
|
6462
|
+
feedback.play("messageSent");
|
|
6463
|
+
const userMsg = makeUserMessage(text, uploaded);
|
|
6464
|
+
const assistantMsg = makeAssistantMessage();
|
|
6465
|
+
messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
|
|
6466
|
+
reducer.attach(assistantMsg);
|
|
6467
|
+
emitMessage(bus, options, "user", text);
|
|
6468
|
+
await streamAssistant(assistantMsg, TRIGGER.submitMessage);
|
|
6469
|
+
},
|
|
6470
|
+
[streaming, transport, bus, options, suggestions.length, messagesSig, reducer, streamAssistant]
|
|
5511
6471
|
);
|
|
5512
6472
|
const handleStop = useCallback6(() => {
|
|
5513
6473
|
log16.info("stop");
|
|
@@ -5711,7 +6671,10 @@ function App({ options, hostElement, bus }) {
|
|
|
5711
6671
|
log16.info("suggestion", { text });
|
|
5712
6672
|
bus.emit("suggestion", { text });
|
|
5713
6673
|
void handleSend(text, []);
|
|
5714
|
-
}
|
|
6674
|
+
},
|
|
6675
|
+
intakePending,
|
|
6676
|
+
onIntakeComplete: handleIntakeComplete,
|
|
6677
|
+
tool: toolInteraction
|
|
5715
6678
|
};
|
|
5716
6679
|
const onSelectSession = (sessionId) => {
|
|
5717
6680
|
void handleSelectHistoryChat(sessionId);
|
|
@@ -5723,12 +6686,12 @@ function App({ options, hostElement, bus }) {
|
|
|
5723
6686
|
const renderSurface = (size) => {
|
|
5724
6687
|
const closeable = isActionVisible("close", effectiveOptions.mode, size);
|
|
5725
6688
|
if (enabledModules.length === 0) {
|
|
5726
|
-
return /* @__PURE__ */
|
|
6689
|
+
return /* @__PURE__ */ jsx37(ModulesEmpty, { strings: effectiveOptions.strings, onClose: closeable ? handleClose : void 0 });
|
|
5727
6690
|
}
|
|
5728
6691
|
if (enabledModules.length === 1 && enabledModules[0]?.layout === "chat") {
|
|
5729
|
-
return /* @__PURE__ */
|
|
6692
|
+
return /* @__PURE__ */ jsx37(Panel, { ...panelProps, panelSize: size });
|
|
5730
6693
|
}
|
|
5731
|
-
return /* @__PURE__ */
|
|
6694
|
+
return /* @__PURE__ */ jsx37(
|
|
5732
6695
|
MessengerHome,
|
|
5733
6696
|
{
|
|
5734
6697
|
panelProps: { ...panelProps, panelSize: size, onClose: closeable ? handleClose : void 0 },
|
|
@@ -5746,7 +6709,7 @@ function App({ options, hostElement, bus }) {
|
|
|
5746
6709
|
void handleSelectHistoryChat(chat.sessionId);
|
|
5747
6710
|
};
|
|
5748
6711
|
const messagesEnabled = enabledModules.some((m) => m.layout === "chat");
|
|
5749
|
-
return /* @__PURE__ */
|
|
6712
|
+
return /* @__PURE__ */ jsx37("div", { class: `${p32}-anchor`, children: /* @__PURE__ */ jsx37(
|
|
5750
6713
|
PageShell,
|
|
5751
6714
|
{
|
|
5752
6715
|
site: parsedSite,
|
|
@@ -5765,15 +6728,15 @@ function App({ options, hostElement, bus }) {
|
|
|
5765
6728
|
}
|
|
5766
6729
|
if (isInlineLike) {
|
|
5767
6730
|
const inlineSize = options.mode === "standalone" ? "fullscreen" : panelSize;
|
|
5768
|
-
return /* @__PURE__ */
|
|
6731
|
+
return /* @__PURE__ */ jsx37("div", { class: `${p32}-anchor`, children: renderSurface(inlineSize) });
|
|
5769
6732
|
}
|
|
5770
6733
|
const drawerEdgeTab = options.mode === "drawer";
|
|
5771
6734
|
const triggerOwnedByPage = options.mode === "modal";
|
|
5772
6735
|
const launcherVisible = !triggerOwnedByPage && !options.launcher.hidden && (!isOpen || launcherLeaving);
|
|
5773
6736
|
const calloutToRender = launcherVisible && !launcherLeaving && !calloutDismissed && !drawerEdgeTab ? effectiveOptions.launcher.callout : null;
|
|
5774
|
-
return /* @__PURE__ */
|
|
6737
|
+
return /* @__PURE__ */ jsxs31("div", { class: `${p32}-anchor`, "data-launcher-size": effectiveOptions.launcher.size, children: [
|
|
5775
6738
|
isOpen ? renderSurface(panelSize) : null,
|
|
5776
|
-
launcherVisible ? /* @__PURE__ */
|
|
6739
|
+
launcherVisible ? /* @__PURE__ */ jsx37(
|
|
5777
6740
|
Launcher,
|
|
5778
6741
|
{
|
|
5779
6742
|
onToggle: handleOpen,
|
|
@@ -5783,7 +6746,7 @@ function App({ options, hostElement, bus }) {
|
|
|
5783
6746
|
edgeTab: drawerEdgeTab
|
|
5784
6747
|
}
|
|
5785
6748
|
) : null,
|
|
5786
|
-
calloutToRender ? /* @__PURE__ */
|
|
6749
|
+
calloutToRender ? /* @__PURE__ */ jsx37(
|
|
5787
6750
|
LauncherCallout,
|
|
5788
6751
|
{
|
|
5789
6752
|
callout: calloutToRender,
|
|
@@ -5982,6 +6945,10 @@ var EVENT_NAMES = [
|
|
|
5982
6945
|
"selectChat",
|
|
5983
6946
|
"suggestion",
|
|
5984
6947
|
"toggleHistory",
|
|
6948
|
+
// Forms + human-in-the-loop
|
|
6949
|
+
"intakeSubmit",
|
|
6950
|
+
"toolResult",
|
|
6951
|
+
"toolDecision",
|
|
5985
6952
|
// Composer / attachments / voice
|
|
5986
6953
|
"attach",
|
|
5987
6954
|
"removeAttachment",
|