@helpai/elements 0.20.0 → 0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/web-component.mjs CHANGED
@@ -447,7 +447,6 @@ var DEFAULT_ATTACHMENTS = {
447
447
  maxCount: 10,
448
448
  accept: "*/*"
449
449
  };
450
- var DEFAULT_WELCOME = { animation: "instant", speed: 60 };
451
450
  var DEFAULT_FEATURES = {
452
451
  files: true,
453
452
  voice: "local",
@@ -517,7 +516,6 @@ function resolveOptions(rawOpts) {
517
516
  showReasoning: behavior.showReasoning ?? false,
518
517
  showToolCalls: behavior.showToolCalls ?? false,
519
518
  popOutUrl: behavior.popOutUrl ?? BRAND.standaloneUrl,
520
- welcome: { ...DEFAULT_WELCOME, ...opts.welcome },
521
519
  features: {
522
520
  files: opts.features?.files ?? DEFAULT_FEATURES.files,
523
521
  voice: opts.features?.voice ?? DEFAULT_FEATURES.voice,
@@ -719,7 +717,6 @@ var SECTION_KEYS = [
719
717
  "launcher",
720
718
  "header",
721
719
  "composer",
722
- "welcome",
723
720
  "feedback",
724
721
  "i18n",
725
722
  "footer",
@@ -980,7 +977,7 @@ function bindHostCommands(host, handlers) {
980
977
  }
981
978
 
982
979
  // src/styles/tokens.css
983
- var tokens_default = ':host{--__P__-accent-user: __BRAND_ACCENT__;--__P__-accent: var(--__P__-accent-user);--__P__-accent-text: __BRAND_ACCENT_TEXT__;--__P__-radius: __BRAND_RADIUS__;--__P__-radius-sm: 8px;--__P__-radius-md: 10px;--__P__-radius-lg: 16px;--__P__-font: __BRAND_FONT__;--__P__-font-display: var(--__P__-font);--__P__-font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;--__P__-bg: oklch(1 0 0);--__P__-bg-elevated: oklch(.9789 .0029 278.3);--__P__-surface: var(--__P__-bg-elevated);--__P__-muted: var(--__P__-fg-muted);--__P__-hover: oklch(.1686 .011 278.3 / .06);--__P__-fg: oklch(.1686 .011 278.3);--__P__-fg-muted: oklch(.4932 .0301 278.3);--__P__-border: oklch(.9312 .0084 278.3);--__P__-border-strong: oklch(.8757 .0131 278.3);--__P__-bubble-user: var(--__P__-accent);--__P__-bubble-user-text: var(--__P__-accent-text);--__P__-bubble-assistant: oklch(.9638 .0058 278.3);--__P__-bubble-assistant-text: var(--__P__-fg);--__P__-on-accent: var(--__P__-accent-text);--__P__-success: oklch(.6456 .1654 151.53);--__P__-warning: oklch(.7135 .1494 74.05);--__P__-danger: oklch(.5966 .1818 24.51);--__P__-danger-text: oklch(.5054 .1905 27.52);--__P__-danger-bg: oklch(.5966 .1818 24.51 / .1);--__P__-neutral: oklch(.7137 .0192 278.3);--__P__-focus: var(--__P__-accent);--__P__-shadow-panel: 0 8px 24px -8px rgba(13, 15, 20, .18), 0 24px 64px -24px rgba(13, 15, 20, .24);--__P__-shadow-card: 0 1px 2px rgba(13, 15, 20, .06), 0 4px 12px -6px rgba(13, 15, 20, .12);--__P__-backdrop: oklch(.1686 .011 278.3 / .55);--__P__-shadow-fab: 0 6px 16px -4px color-mix(in oklch, var(--__P__-accent) 45%, transparent), 0 12px 32px -12px rgba(13, 15, 20, .25);--__P__-z-fab: 2147483600;--__P__-z-panel: 2147483601;--__P__-panel-w: 380px;--__P__-panel-h: 600px;--__P__-fab-size: 56px;--__P__-space-1: 4px;--__P__-space-2: 8px;--__P__-space-3: 12px;--__P__-space-4: 16px;--__P__-space-5: 20px;--__P__-space-6: 24px;--__P__-space-8: 32px;--__P__-text-scale: 1;--__P__-text-xs: calc(12px * var(--__P__-text-scale));--__P__-text-sm: calc(13px * var(--__P__-text-scale));--__P__-text-base: calc(15px * var(--__P__-text-scale));--__P__-text-md: calc(16px * var(--__P__-text-scale));--__P__-text-lg: calc(18px * var(--__P__-text-scale));--__P__-text-xl: calc(22px * var(--__P__-text-scale));--__P__-text-2xl: calc(30px * var(--__P__-text-scale))}:host([data-text-size="small"]){--__P__-text-scale: .9}:host([data-text-size="large"]){--__P__-text-scale: 1.15}:host{--__P__-ease: cubic-bezier(.2, .7, .2, 1);--__P__-ease-out: cubic-bezier(.2, .7, .2, 1);--__P__-ease-in: cubic-bezier(.4, 0, 1, 1);--__P__-ease-in-out: cubic-bezier(.65, 0, .35, 1);--__P__-dur-quick: .12s;--__P__-dur-base: .22s;--__P__-dur-slow: .32s;font-family:var(--__P__-font);color:var(--__P__-fg);color-scheme:light;--__P__-color-scheme: light}:host([data-theme="dark"]){--__P__-bg: oklch(.1783 .0128 278.3);--__P__-bg-elevated: oklch(.2232 .0182 278.3);--__P__-fg: oklch(.9368 .01 278.3);--__P__-fg-muted: oklch(.7048 .0296 278.3);--__P__-border: oklch(.2752 .0266 278.3);--__P__-border-strong: oklch(.335 .0291 278.3);--__P__-hover: oklch(.9368 .01 278.3 / .08);--__P__-bubble-assistant: oklch(.2474 .0311 278.3);--__P__-bubble-assistant-text: var(--__P__-fg);--__P__-danger-text: oklch(.8077 .1035 19.57);--__P__-danger-bg: oklch(.5966 .1818 24.51 / .18);--__P__-shadow-panel: 0 8px 24px -8px rgba(0, 0, 0, .6), 0 24px 64px -24px rgba(0, 0, 0, .7);--__P__-shadow-card: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 12px -6px rgba(0, 0, 0, .5);--__P__-backdrop: rgba(0, 0, 0, .65);color-scheme:dark;--__P__-color-scheme: dark}@media(prefers-color-scheme:dark){:host([data-theme="auto"]){--__P__-bg: oklch(.1783 .0128 278.3);--__P__-bg-elevated: oklch(.2232 .0182 278.3);--__P__-fg: oklch(.9368 .01 278.3);--__P__-fg-muted: oklch(.7048 .0296 278.3);--__P__-border: oklch(.2752 .0266 278.3);--__P__-border-strong: oklch(.335 .0291 278.3);--__P__-hover: oklch(.9368 .01 278.3 / .08);--__P__-bubble-assistant: oklch(.2474 .0311 278.3);--__P__-bubble-assistant-text: var(--__P__-fg);--__P__-shadow-panel: 0 8px 24px -8px rgba(0, 0, 0, .6), 0 24px 64px -24px rgba(0, 0, 0, .7);color-scheme:dark;--__P__-color-scheme: dark}}@supports (color: oklch(from red l c h)){:host{--__P__-accent: oklch(from var(--__P__-accent-user) clamp(.3, l, .62) c h);--__P__-accent-text: oklch(from var(--__P__-accent) clamp(0, (l / .623 - 1) * -infinity, 1) 0 h)}:host([data-theme="dark"]){--__P__-accent: oklch(from var(--__P__-accent-user) clamp(.65, l, .85) c h)}@media(prefers-color-scheme:dark){:host([data-theme="auto"]){--__P__-accent: oklch(from var(--__P__-accent-user) clamp(.65, l, .85) c h)}}}@media(prefers-reduced-motion:reduce){:host{--__P__-dur-quick: 1ms;--__P__-dur-base: 1ms;--__P__-dur-slow: 1ms}}\n';
980
+ var tokens_default = ':host{--__P__-accent-user: __BRAND_ACCENT__;--__P__-accent: var(--__P__-accent-user);--__P__-accent-text-user: __BRAND_ACCENT_TEXT__;--__P__-accent-text: var(--__P__-accent-text-user);--__P__-radius: __BRAND_RADIUS__;--__P__-radius-sm: 8px;--__P__-radius-md: 10px;--__P__-radius-lg: 16px;--__P__-font: __BRAND_FONT__;--__P__-font-display: var(--__P__-font);--__P__-font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;--__P__-bg: oklch(1 0 0);--__P__-bg-elevated: oklch(.9789 .0029 278.3);--__P__-surface: var(--__P__-bg-elevated);--__P__-muted: var(--__P__-fg-muted);--__P__-hover: oklch(.1686 .011 278.3 / .06);--__P__-fg: oklch(.1686 .011 278.3);--__P__-fg-muted: oklch(.4932 .0301 278.3);--__P__-border: oklch(.9312 .0084 278.3);--__P__-border-strong: oklch(.8757 .0131 278.3);--__P__-bubble-user: var(--__P__-accent);--__P__-bubble-user-text: var(--__P__-accent-text);--__P__-bubble-assistant: oklch(.9638 .0058 278.3);--__P__-bubble-assistant-text: var(--__P__-fg);--__P__-on-accent: var(--__P__-accent-text);--__P__-success: oklch(.6456 .1654 151.53);--__P__-warning: oklch(.7135 .1494 74.05);--__P__-danger: oklch(.5966 .1818 24.51);--__P__-danger-text: oklch(.5054 .1905 27.52);--__P__-danger-bg: oklch(.5966 .1818 24.51 / .1);--__P__-neutral: oklch(.7137 .0192 278.3);--__P__-focus: var(--__P__-accent);--__P__-shadow-panel: 0 8px 24px -8px rgba(13, 15, 20, .18), 0 24px 64px -24px rgba(13, 15, 20, .24);--__P__-shadow-card: 0 1px 2px rgba(13, 15, 20, .06), 0 4px 12px -6px rgba(13, 15, 20, .12);--__P__-backdrop: oklch(.1686 .011 278.3 / .55);--__P__-shadow-fab: 0 6px 16px -4px color-mix(in oklch, var(--__P__-accent) 45%, transparent), 0 12px 32px -12px rgba(13, 15, 20, .25);--__P__-z-fab: 2147483600;--__P__-z-panel: 2147483601;--__P__-panel-w: 380px;--__P__-panel-h: 600px;--__P__-fab-size: 56px;--__P__-space-1: 4px;--__P__-space-2: 8px;--__P__-space-3: 12px;--__P__-space-4: 16px;--__P__-space-5: 20px;--__P__-space-6: 24px;--__P__-space-8: 32px;--__P__-text-scale: 1;--__P__-text-xs: calc(12px * var(--__P__-text-scale));--__P__-text-sm: calc(13px * var(--__P__-text-scale));--__P__-text-base: calc(15px * var(--__P__-text-scale));--__P__-text-md: calc(16px * var(--__P__-text-scale));--__P__-text-lg: calc(18px * var(--__P__-text-scale));--__P__-text-xl: calc(22px * var(--__P__-text-scale));--__P__-text-2xl: calc(30px * var(--__P__-text-scale))}:host([data-text-size="small"]){--__P__-text-scale: .9}:host([data-text-size="large"]){--__P__-text-scale: 1.15}:host{--__P__-ease: cubic-bezier(.2, .7, .2, 1);--__P__-ease-out: cubic-bezier(.2, .7, .2, 1);--__P__-ease-in: cubic-bezier(.4, 0, 1, 1);--__P__-ease-in-out: cubic-bezier(.65, 0, .35, 1);--__P__-dur-quick: .12s;--__P__-dur-base: .22s;--__P__-dur-slow: .32s;font-family:var(--__P__-font);color:var(--__P__-fg);color-scheme:light;--__P__-color-scheme: light}:host([data-theme="dark"]){--__P__-bg: oklch(.1783 .0128 278.3);--__P__-bg-elevated: oklch(.2232 .0182 278.3);--__P__-fg: oklch(.9368 .01 278.3);--__P__-fg-muted: oklch(.7048 .0296 278.3);--__P__-border: oklch(.2752 .0266 278.3);--__P__-border-strong: oklch(.335 .0291 278.3);--__P__-hover: oklch(.9368 .01 278.3 / .08);--__P__-bubble-assistant: oklch(.2474 .0311 278.3);--__P__-bubble-assistant-text: var(--__P__-fg);--__P__-danger-text: oklch(.8077 .1035 19.57);--__P__-danger-bg: oklch(.5966 .1818 24.51 / .18);--__P__-shadow-panel: 0 8px 24px -8px rgba(0, 0, 0, .6), 0 24px 64px -24px rgba(0, 0, 0, .7);--__P__-shadow-card: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 12px -6px rgba(0, 0, 0, .5);--__P__-backdrop: rgba(0, 0, 0, .65);color-scheme:dark;--__P__-color-scheme: dark}@media(prefers-color-scheme:dark){:host([data-theme="auto"]){--__P__-bg: oklch(.1783 .0128 278.3);--__P__-bg-elevated: oklch(.2232 .0182 278.3);--__P__-fg: oklch(.9368 .01 278.3);--__P__-fg-muted: oklch(.7048 .0296 278.3);--__P__-border: oklch(.2752 .0266 278.3);--__P__-border-strong: oklch(.335 .0291 278.3);--__P__-hover: oklch(.9368 .01 278.3 / .08);--__P__-bubble-assistant: oklch(.2474 .0311 278.3);--__P__-bubble-assistant-text: var(--__P__-fg);--__P__-shadow-panel: 0 8px 24px -8px rgba(0, 0, 0, .6), 0 24px 64px -24px rgba(0, 0, 0, .7);color-scheme:dark;--__P__-color-scheme: dark}}@supports (color: oklch(from red l c h)){:host{--__P__-accent: oklch(from var(--__P__-accent-user) clamp(.3, l, .62) c h);--__P__-accent-text: oklch(from var(--__P__-accent) clamp(0, (l / .623 - 1) * -infinity, 1) 0 h)}:host([data-theme="dark"]){--__P__-accent: oklch(from var(--__P__-accent-user) clamp(.65, l, .85) c h)}@media(prefers-color-scheme:dark){:host([data-theme="auto"]){--__P__-accent: oklch(from var(--__P__-accent-user) clamp(.65, l, .85) c h)}}}@media(prefers-reduced-motion:reduce){:host{--__P__-dur-quick: 1ms;--__P__-dur-base: 1ms;--__P__-dur-slow: 1ms}}\n';
984
981
 
985
982
  // src/styles/reset.css
986
983
  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';
@@ -1076,7 +1073,7 @@ function attachAdoptedSheet(shadow, doc) {
1076
1073
  function applyThemeOverrides(host, overrides) {
1077
1074
  const p33 = BRAND.cssPrefix;
1078
1075
  if (overrides.accent) host.style.setProperty(`--${p33}-accent-user`, overrides.accent);
1079
- if (overrides.accentText) host.style.setProperty(`--${p33}-accent-text`, overrides.accentText);
1076
+ if (overrides.accentText) host.style.setProperty(`--${p33}-accent-text-user`, overrides.accentText);
1080
1077
  if (overrides.radius) host.style.setProperty(`--${p33}-radius`, overrides.radius);
1081
1078
  if (overrides.fontFamily) host.style.setProperty(`--${p33}-font`, overrides.fontFamily);
1082
1079
  }
@@ -1915,15 +1912,6 @@ function makeAssistantMessage() {
1915
1912
  partsSig: signal([])
1916
1913
  };
1917
1914
  }
1918
- function makeTypewriterMessage(m) {
1919
- return {
1920
- id: m.id,
1921
- role: m.role,
1922
- createdAt: Date.now(),
1923
- status: "streaming",
1924
- partsSig: signal([{ kind: "text", id: `${m.id}-t0`, textSig: signal(""), doneSig: signal(false) }])
1925
- };
1926
- }
1927
1915
  function makeInstantWelcomeMessage(m) {
1928
1916
  return toReactive({
1929
1917
  id: m.id,
@@ -4817,6 +4805,7 @@ function LoadingSpinner({ label }) {
4817
4805
  import { jsx as jsx17, jsxs as jsxs14 } from "preact/jsx-runtime";
4818
4806
  var p15 = BRAND.cssPrefix;
4819
4807
  var STICK_THRESHOLD = 120;
4808
+ var INTERACTION_GRACE_MS = 350;
4820
4809
  var DIVIDER_IDLE_MS = 1200;
4821
4810
  function MessageList({
4822
4811
  messagesSig,
@@ -4837,6 +4826,8 @@ function MessageList({
4837
4826
  const hasHydratedRef = useRef5(false);
4838
4827
  const detachedRef = useRef5(false);
4839
4828
  const interactingRef = useRef5(false);
4829
+ const interactionEndedAtRef = useRef5(0);
4830
+ const inInteractionGrace = () => interactingRef.current || performance.now() - interactionEndedAtRef.current < INTERACTION_GRACE_MS;
4840
4831
  const autoPinAtRef = useRef5(0);
4841
4832
  const pinBottom = (el) => {
4842
4833
  autoPinAtRef.current = performance.now();
@@ -4877,7 +4868,7 @@ function MessageList({
4877
4868
  pinBottom(el);
4878
4869
  return;
4879
4870
  }
4880
- if (detachedRef.current || interactingRef.current) return;
4871
+ if (detachedRef.current || inInteractionGrace()) return;
4881
4872
  const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
4882
4873
  if (distanceFromBottom < STICK_THRESHOLD) pinBottom(el);
4883
4874
  }, [messages.value.length]);
@@ -4887,7 +4878,7 @@ function MessageList({
4887
4878
  const last = messages.value.at(-1);
4888
4879
  if (!last) return;
4889
4880
  const pinIfNear = () => {
4890
- if (detachedRef.current || interactingRef.current) return;
4881
+ if (detachedRef.current || inInteractionGrace()) return;
4891
4882
  const distance = el.scrollHeight - el.scrollTop - el.clientHeight;
4892
4883
  if (distance < STICK_THRESHOLD * 2) pinBottom(el);
4893
4884
  };
@@ -4937,6 +4928,7 @@ function MessageList({
4937
4928
  };
4938
4929
  const endInteraction = () => {
4939
4930
  interactingRef.current = false;
4931
+ interactionEndedAtRef.current = performance.now();
4940
4932
  };
4941
4933
  const onPointerDown = () => {
4942
4934
  interactingRef.current = true;
@@ -6309,55 +6301,6 @@ function ModulesEmpty({ strings, onClose }) {
6309
6301
  );
6310
6302
  }
6311
6303
 
6312
- // src/ui/welcome-animator.ts
6313
- async function animateWelcomeSequence(reactives, payloads, charsPerSecond, abort) {
6314
- for (let i = 0; i < reactives.length; i++) {
6315
- if (abort.aborted) return;
6316
- const msg = reactives[i];
6317
- const payload = payloads[i];
6318
- if (!msg || !payload) continue;
6319
- await animateTypewriter(msg, payload.text, charsPerSecond, abort);
6320
- }
6321
- }
6322
- function animateTypewriter(msg, text, charsPerSecond, abort) {
6323
- return new Promise((resolve) => {
6324
- const part = msg.partsSig.value[0];
6325
- if (!part || part.kind !== "text") {
6326
- resolve();
6327
- return;
6328
- }
6329
- const finish = () => {
6330
- part.textSig.value = text;
6331
- part.doneSig.value = true;
6332
- msg.status = "complete";
6333
- msg.partsSig.value = [...msg.partsSig.value];
6334
- resolve();
6335
- };
6336
- if (typeof requestAnimationFrame === "undefined") {
6337
- finish();
6338
- return;
6339
- }
6340
- const totalMs = text.length / Math.max(1, charsPerSecond) * 1e3;
6341
- const start = performance.now();
6342
- const tick = (now) => {
6343
- if (abort.aborted) return finish();
6344
- const progress = totalMs === 0 ? 1 : Math.min(1, (now - start) / totalMs);
6345
- part.textSig.value = text.slice(0, Math.floor(progress * text.length));
6346
- if (progress >= 1) return finish();
6347
- rafId = requestAnimationFrame(tick);
6348
- };
6349
- let rafId = requestAnimationFrame(tick);
6350
- abort.addEventListener(
6351
- "abort",
6352
- () => {
6353
- cancelAnimationFrame(rafId);
6354
- finish();
6355
- },
6356
- { once: true }
6357
- );
6358
- });
6359
- }
6360
-
6361
6304
  // src/ui/use-launcher-callout.ts
6362
6305
  import { useCallback as useCallback5, useEffect as useEffect16, useState as useState12 } from "preact/hooks";
6363
6306
  function useLauncherCallout({ callout, persistence }) {
@@ -6436,7 +6379,6 @@ function App({ options, hostElement, bus }) {
6436
6379
  const [agent, setAgent] = useState13(null);
6437
6380
  const [suggestions, setSuggestions] = useState13([]);
6438
6381
  const [activeCancel, setActiveCancel] = useState13(null);
6439
- const welcomeAbortRef = useRef9(null);
6440
6382
  const [parsedSite, setParsedSite] = useState13(void 0);
6441
6383
  const [parsedBlocks, setParsedBlocks] = useState13(void 0);
6442
6384
  const [sidebarCollapsed, setSidebarCollapsed] = useState13(() => persistence.loadSidebarCollapsed() ?? false);
@@ -6520,19 +6462,9 @@ function App({ options, hostElement, bus }) {
6520
6462
  const playWelcome = useCallback6(
6521
6463
  (welcomeMessages) => {
6522
6464
  if (!welcomeMessages || welcomeMessages.length === 0) return;
6523
- const { animation, speed } = options.welcome;
6524
- if (animation === "instant") {
6525
- messagesSig.value = welcomeMessages.map(makeInstantWelcomeMessage);
6526
- return;
6527
- }
6528
- welcomeAbortRef.current?.abort();
6529
- const ctrl = new AbortController();
6530
- welcomeAbortRef.current = ctrl;
6531
- const reactives = welcomeMessages.map(makeTypewriterMessage);
6532
- messagesSig.value = reactives;
6533
- void animateWelcomeSequence(reactives, welcomeMessages, speed, ctrl.signal);
6465
+ messagesSig.value = welcomeMessages.map(makeInstantWelcomeMessage);
6534
6466
  },
6535
- [messagesSig, options.welcome]
6467
+ [messagesSig]
6536
6468
  );
6537
6469
  const connectGenRef = useRef9(0);
6538
6470
  const runStartConversation = useCallback6(
@@ -6971,7 +6903,6 @@ function App({ options, hostElement, bus }) {
6971
6903
  log16.info("clear \u2192 new conversation", { wasStreaming: streaming });
6972
6904
  bus.emit("clear", void 0);
6973
6905
  if (streaming) activeCancel?.();
6974
- welcomeAbortRef.current?.abort();
6975
6906
  messagesSig.value = [];
6976
6907
  conversationIdSig.value = void 0;
6977
6908
  persistence.clearConversation();