@helpai/elements 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/configurator.mjs +145 -158
- 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 +27 -27
- package/elements.js.map +4 -4
- package/index.d.ts +1 -18
- package/index.mjs +4 -77
- package/package.json +1 -1
- package/schema.d.ts +50 -71
- package/schema.json +0 -72
- package/schema.mjs +147 -163
- package/style.css +1 -1
- package/web-component.mjs +4 -77
package/schema.mjs
CHANGED
|
@@ -17,7 +17,7 @@ var localeSchema = z.string().min(1).max(35).describe("BCP-47 locale tag (e.g. `
|
|
|
17
17
|
var uuid7Schema = z.uuidv7().describe("UUID v7 (RFC 9562) \u2014 the single id format for visitor / conversation / message / file / content ids.");
|
|
18
18
|
|
|
19
19
|
// src/schema/widget.ts
|
|
20
|
-
import { z as
|
|
20
|
+
import { z as z15 } from "zod";
|
|
21
21
|
|
|
22
22
|
// src/schema/widget/presentation.ts
|
|
23
23
|
import { z as z3 } from "zod";
|
|
@@ -341,33 +341,21 @@ var composerOptionsSchema = z10.object({
|
|
|
341
341
|
]
|
|
342
342
|
});
|
|
343
343
|
|
|
344
|
-
// src/schema/widget/welcome.ts
|
|
345
|
-
import { z as z11 } from "zod";
|
|
346
|
-
var welcomeAnimationSchema = z11.enum(["typewriter", "instant"]);
|
|
347
|
-
var welcomeOptionsSchema = z11.object({
|
|
348
|
-
animation: welcomeAnimationSchema.default("instant").describe(
|
|
349
|
-
"How welcome messages render \u2014 `typewriter` types each message in character-by-character; `instant` shows them whole."
|
|
350
|
-
),
|
|
351
|
-
speed: z11.number().int().min(1).max(2e3).default(60).describe("Typewriter speed in characters per second. Only meaningful when `animation = typewriter`.")
|
|
352
|
-
}).loose().describe("How welcome messages render \u2014 instant by default; opt into a typewriter effect with adjustable cps speed.").meta({
|
|
353
|
-
examples: [{ animation: "instant" }, { animation: "typewriter", speed: 60 }]
|
|
354
|
-
});
|
|
355
|
-
|
|
356
344
|
// src/schema/widget/footer.ts
|
|
357
|
-
import { z as
|
|
358
|
-
var poweredBySchema =
|
|
359
|
-
text:
|
|
360
|
-
href:
|
|
361
|
-
logoUrl:
|
|
345
|
+
import { z as z11 } from "zod";
|
|
346
|
+
var poweredBySchema = z11.object({
|
|
347
|
+
text: z11.string().max(200).optional().describe("Visible attribution text (e.g. `Powered by Help AI`)."),
|
|
348
|
+
href: z11.url().max(2048).optional().describe("Click target \u2014 the attribution becomes a link. Must be a full URL (`https://\u2026`)."),
|
|
349
|
+
logoUrl: z11.url().max(2048).optional().describe("Small logo rendered before the text. Must be a full URL.")
|
|
362
350
|
}).loose().describe('"Powered by \u2026" attribution shown below the composer.').meta({
|
|
363
351
|
examples: [
|
|
364
352
|
{ text: "Powered by Help AI" },
|
|
365
353
|
{ text: "Powered by Help AI", href: "https://help.ai", logoUrl: "https://help.ai/logo.svg" }
|
|
366
354
|
]
|
|
367
355
|
});
|
|
368
|
-
var footerSchema =
|
|
356
|
+
var footerSchema = z11.object({
|
|
369
357
|
poweredBy: poweredBySchema.optional(),
|
|
370
|
-
composerDisclaimer:
|
|
358
|
+
composerDisclaimer: z11.string().max(500).optional().describe("Small muted text under the composer (like ChatGPT's 'ChatGPT can make mistakes.'). Empty = hidden.")
|
|
371
359
|
}).loose().describe("Footer \u2014 attribution + composer disclaimer.").meta({
|
|
372
360
|
examples: [
|
|
373
361
|
{ poweredBy: { text: "Powered by Help AI", href: "https://help.ai" } },
|
|
@@ -376,8 +364,8 @@ var footerSchema = z12.object({
|
|
|
376
364
|
});
|
|
377
365
|
|
|
378
366
|
// src/schema/widget/forms.ts
|
|
379
|
-
import { z as
|
|
380
|
-
var fieldTypeSchema =
|
|
367
|
+
import { z as z12 } from "zod";
|
|
368
|
+
var fieldTypeSchema = z12.enum([
|
|
381
369
|
"text",
|
|
382
370
|
"email",
|
|
383
371
|
"tel",
|
|
@@ -391,59 +379,59 @@ var fieldTypeSchema = z13.enum([
|
|
|
391
379
|
"checkbox",
|
|
392
380
|
"multiselect"
|
|
393
381
|
]);
|
|
394
|
-
var fieldOptionSchema =
|
|
395
|
-
value:
|
|
396
|
-
label:
|
|
397
|
-
description:
|
|
382
|
+
var fieldOptionSchema = z12.object({
|
|
383
|
+
value: z12.string().min(1).max(200).describe("The value recorded when this choice is picked."),
|
|
384
|
+
label: z12.string().min(1).max(200).optional().describe("Display text; falls back to `value`."),
|
|
385
|
+
description: z12.string().max(280).optional().describe("Optional sub-label under the choice.")
|
|
398
386
|
}).loose();
|
|
399
|
-
var fieldValidationSchema =
|
|
400
|
-
pattern:
|
|
401
|
-
minLength:
|
|
402
|
-
maxLength:
|
|
403
|
-
min:
|
|
404
|
-
max:
|
|
405
|
-
minSelections:
|
|
406
|
-
maxSelections:
|
|
387
|
+
var fieldValidationSchema = z12.object({
|
|
388
|
+
pattern: z12.string().max(500).optional().describe("Regex source string \u2014 text-like fields (e.g. `^\\d{5}$`)."),
|
|
389
|
+
minLength: z12.number().int().min(0).max(1e4).optional(),
|
|
390
|
+
maxLength: z12.number().int().min(1).max(1e4).optional(),
|
|
391
|
+
min: z12.number().optional().describe("Minimum \u2014 `number` fields."),
|
|
392
|
+
max: z12.number().optional().describe("Maximum \u2014 `number` fields."),
|
|
393
|
+
minSelections: z12.number().int().min(0).max(50).optional().describe("Minimum picks \u2014 `multiselect`."),
|
|
394
|
+
maxSelections: z12.number().int().min(1).max(50).optional().describe("Maximum picks \u2014 `multiselect`.")
|
|
407
395
|
}).loose();
|
|
408
|
-
var formFieldSchema =
|
|
409
|
-
name:
|
|
410
|
-
label:
|
|
396
|
+
var formFieldSchema = z12.object({
|
|
397
|
+
name: z12.string().min(1).max(80).describe("Stable key the answer is recorded under (e.g. `email`)."),
|
|
398
|
+
label: z12.string().min(1).max(200).describe("Visible field label."),
|
|
411
399
|
type: fieldTypeSchema.describe("Field renderer + built-in validation (email/tel/url/number/date/time checked)."),
|
|
412
|
-
placeholder:
|
|
413
|
-
required:
|
|
414
|
-
defaultValue:
|
|
415
|
-
options:
|
|
400
|
+
placeholder: z12.string().max(200).optional(),
|
|
401
|
+
required: z12.boolean().optional().default(true).describe("Must be answered to submit. `false` allows skipping."),
|
|
402
|
+
defaultValue: z12.string().max(2e3).optional().describe("Pre-filled value (comma-join for `multiselect`)."),
|
|
403
|
+
options: z12.array(fieldOptionSchema).max(50).optional().describe("Choices for `select` / `radio` / `multiselect`."),
|
|
416
404
|
validation: fieldValidationSchema.optional(),
|
|
417
|
-
allowOther:
|
|
418
|
-
validationHint:
|
|
405
|
+
allowOther: z12.boolean().optional().describe("`select`/`radio`/`multiselect` \u2014 allow a free-text 'Other' answer."),
|
|
406
|
+
validationHint: z12.string().max(280).optional().describe("Small helper line under the field.")
|
|
419
407
|
}).loose();
|
|
420
|
-
var formTriggerSchema =
|
|
408
|
+
var formTriggerSchema = z12.string().regex(
|
|
421
409
|
/^(pre-chat|conversation-closed|panel-close|manual|after-messages:\d+|idle:\d+|page-area:.+)$/,
|
|
422
410
|
"Unrecognised form trigger"
|
|
423
411
|
).describe(
|
|
424
412
|
"When the form fires: `pre-chat`, `after-messages:N`, `conversation-closed`, `panel-close`, `idle:Nseconds`, `page-area:<area>`, or `manual`."
|
|
425
413
|
);
|
|
426
|
-
var formConditionSchema =
|
|
427
|
-
missingContext:
|
|
428
|
-
pageArea:
|
|
429
|
-
minMessages:
|
|
430
|
-
maxMessages:
|
|
414
|
+
var formConditionSchema = z12.object({
|
|
415
|
+
missingContext: z12.array(z12.string().max(80)).max(20).optional().describe("Only show if `userContext` lacks ALL of these keys (progressive profiling)."),
|
|
416
|
+
pageArea: z12.union([z12.string().max(64), z12.array(z12.string().max(64)).max(20)]).optional().describe("Only on these `pageContext.area` values."),
|
|
417
|
+
minMessages: z12.number().int().min(0).max(1e3).optional(),
|
|
418
|
+
maxMessages: z12.number().int().min(0).max(1e3).optional()
|
|
431
419
|
}).loose();
|
|
432
|
-
var formDefSchema =
|
|
433
|
-
id:
|
|
434
|
-
on:
|
|
420
|
+
var formDefSchema = z12.object({
|
|
421
|
+
id: z12.string().min(1).max(80).describe("Stable id \u2014 persistence dedupe + `manual` openForm(id)."),
|
|
422
|
+
on: z12.union([formTriggerSchema, z12.array(formTriggerSchema).min(1).max(8)]).describe("Trigger(s) that surface this form."),
|
|
435
423
|
when: formConditionSchema.optional().describe("Extra eligibility predicate evaluated when a trigger fires."),
|
|
436
|
-
fields:
|
|
437
|
-
title:
|
|
438
|
-
description:
|
|
439
|
-
submitLabel:
|
|
440
|
-
skippable:
|
|
441
|
-
frequency:
|
|
442
|
-
mirrorToContext:
|
|
424
|
+
fields: z12.array(formFieldSchema).max(20).default([]).describe("The questions, in order. \u22651 required to show."),
|
|
425
|
+
title: z12.string().max(120).optional(),
|
|
426
|
+
description: z12.string().max(500).optional(),
|
|
427
|
+
submitLabel: z12.string().max(60).optional(),
|
|
428
|
+
skippable: z12.boolean().default(false).describe("Show a Skip control so the visitor can dismiss the form."),
|
|
429
|
+
frequency: z12.enum(["once", "conversation", "always"]).default("once").describe("`once` (per device, persisted), `conversation` (re-eligible each new conversation), or `always`."),
|
|
430
|
+
mirrorToContext: z12.boolean().default(true).describe(
|
|
443
431
|
"Mirror the answers into `userContext` so they ride every request. Set `false` for PII (DOB, policy #, symptoms) \u2014 those then go only to the submit endpoint."
|
|
444
432
|
)
|
|
445
433
|
}).loose();
|
|
446
|
-
var formsSchema =
|
|
434
|
+
var formsSchema = z12.array(formDefSchema).max(20).describe(
|
|
447
435
|
"Event-driven forms \u2014 an ordered list (order = priority). Each binds to trigger event(s), gates the chat until submit/skip, dedupes by frequency, and records via `endpoints.submitForm`. Generic across verticals."
|
|
448
436
|
).meta({
|
|
449
437
|
examples: [
|
|
@@ -486,9 +474,9 @@ var formsSchema = z13.array(formDefSchema).max(20).describe(
|
|
|
486
474
|
});
|
|
487
475
|
|
|
488
476
|
// src/schema/widget/i18n.ts
|
|
489
|
-
import { z as
|
|
490
|
-
var localeStringsSchema =
|
|
491
|
-
var stringsOverrideSchema =
|
|
477
|
+
import { z as z13 } from "zod";
|
|
478
|
+
var localeStringsSchema = z13.record(z13.string(), z13.string());
|
|
479
|
+
var stringsOverrideSchema = z13.union([localeStringsSchema, z13.record(localeSchema, localeStringsSchema)]).describe(
|
|
492
480
|
"Per-instance UI string overrides. Flat = active-locale only; nested = multi-locale map. Both forms are partial \u2014 missing keys fall through to built-in defaults."
|
|
493
481
|
).meta({
|
|
494
482
|
examples: [
|
|
@@ -499,10 +487,10 @@ var stringsOverrideSchema = z14.union([localeStringsSchema, z14.record(localeSch
|
|
|
499
487
|
}
|
|
500
488
|
]
|
|
501
489
|
});
|
|
502
|
-
var i18nSchema =
|
|
490
|
+
var i18nSchema = z13.object({
|
|
503
491
|
locale: localeSchema.optional().describe("BCP-47 locale tag forced for this widget instance (e.g. `fr-CA`). Page-owner explicit override."),
|
|
504
|
-
defaultLocale:
|
|
505
|
-
availableLocales:
|
|
492
|
+
defaultLocale: z13.union([z13.literal("auto"), localeSchema]).default("auto").describe("Initial / fallback locale for users who haven't picked one. `auto` sniffs `navigator.language`."),
|
|
493
|
+
availableLocales: z13.array(localeSchema).max(200).optional().describe("BCP-47 locale tags shown in the runtime language switcher. Hidden when fewer than 2 entries."),
|
|
506
494
|
strings: stringsOverrideSchema.optional()
|
|
507
495
|
}).loose().describe("Locale + i18n overrides.").meta({
|
|
508
496
|
examples: [
|
|
@@ -513,44 +501,44 @@ var i18nSchema = z14.object({
|
|
|
513
501
|
});
|
|
514
502
|
|
|
515
503
|
// src/schema/widget/modules.ts
|
|
516
|
-
import { z as
|
|
517
|
-
var moduleLayoutSchema =
|
|
518
|
-
var moduleSchema =
|
|
519
|
-
label:
|
|
504
|
+
import { z as z14 } from "zod";
|
|
505
|
+
var moduleLayoutSchema = z14.enum(["chat", "home", "help", "news"]);
|
|
506
|
+
var moduleSchema = z14.object({
|
|
507
|
+
label: z14.string().min(1).max(40).describe(
|
|
520
508
|
"Tab label \u2014 an i18n key (resolved against the i18n strings, e.g. `tabHome`) or a literal. Translations ride `i18n.strings`."
|
|
521
509
|
),
|
|
522
510
|
layout: moduleLayoutSchema.describe(
|
|
523
511
|
"UI layout that renders this tab: `chat` (the conversation), `home`, `help`, or `news`."
|
|
524
512
|
),
|
|
525
|
-
contentTags:
|
|
513
|
+
contentTags: z14.array(z14.string().max(60)).max(20).optional().describe(
|
|
526
514
|
"Content tags this tab scopes to \u2014 the `tags` filter on `GET /ai/agent/content` (matches content tagged with ANY of them). Omit for the `chat` layout."
|
|
527
515
|
),
|
|
528
|
-
id:
|
|
516
|
+
id: z14.string().max(60).optional().describe(
|
|
529
517
|
"Stable id for navigation + last-tab persistence. Defaults to the first `contentTags` entry, else `layout`."
|
|
530
518
|
),
|
|
531
519
|
// ── `home` layout config (flat feature flags — no block authoring) ──────
|
|
532
|
-
brandName:
|
|
533
|
-
showGreeting:
|
|
534
|
-
greetingText:
|
|
535
|
-
userAvatars:
|
|
536
|
-
|
|
537
|
-
name:
|
|
538
|
-
avatar:
|
|
539
|
-
role:
|
|
520
|
+
brandName: z14.string().max(80).optional().describe("`home` \u2014 hero wordmark (e.g. your company name)."),
|
|
521
|
+
showGreeting: z14.boolean().optional().describe("`home` \u2014 show the greeting hero (default true)."),
|
|
522
|
+
greetingText: z14.string().max(280).optional().describe("`home` \u2014 override the greeting headline (default 'How can we help?'); supports a `{name}` token."),
|
|
523
|
+
userAvatars: z14.array(
|
|
524
|
+
z14.object({
|
|
525
|
+
name: z14.string().min(1).max(80),
|
|
526
|
+
avatar: z14.string().max(2048).optional().describe("Image URL; falls back to initials of `name`."),
|
|
527
|
+
role: z14.string().max(80).optional()
|
|
540
528
|
}).loose()
|
|
541
529
|
).max(10).optional().describe("`home` \u2014 team/agent avatars shown in the hero."),
|
|
542
|
-
showSearchBar:
|
|
543
|
-
showRecentConversations:
|
|
544
|
-
status:
|
|
545
|
-
text:
|
|
546
|
-
level:
|
|
530
|
+
showSearchBar: z14.boolean().optional().describe("`home` \u2014 show the 'Search for help' bar (default true)."),
|
|
531
|
+
showRecentConversations: z14.boolean().optional().describe("`home` \u2014 show the visitor's most recent conversation card (default true)."),
|
|
532
|
+
status: z14.object({
|
|
533
|
+
text: z14.string().min(1).max(120),
|
|
534
|
+
level: z14.string().max(40).optional().describe(
|
|
547
535
|
"`home` \u2014 status severity, drives the status icon colour. Free text; `operational` (green, default), `degraded` (amber), and `down` (red) are styled, any other value falls back to the operational style."
|
|
548
536
|
).meta({ examples: ["operational", "degraded", "down"] }),
|
|
549
|
-
url:
|
|
537
|
+
url: z14.string().max(2048).optional().describe("Opens in an in-widget iframe when tapped.")
|
|
550
538
|
}).optional().describe("`home` \u2014 system-status card. Omit to hide."),
|
|
551
|
-
contentBlockTitle:
|
|
539
|
+
contentBlockTitle: z14.string().max(80).optional().describe("`home` \u2014 heading for the content list built from `contentTags` (default 'Popular articles').")
|
|
552
540
|
}).loose();
|
|
553
|
-
var modulesSchema =
|
|
541
|
+
var modulesSchema = z14.array(moduleSchema).max(4).describe(
|
|
554
542
|
"Messenger tabs \u2014 an ordered list of up to 4 tabs, each picking a `layout` + optional content `contentTags` (the content scope) + a translatable `label`. One tab \u2192 no tab bar (just that content); zero \u2192 an empty state. Floating / drawer / modal only."
|
|
555
543
|
).meta({
|
|
556
544
|
examples: [
|
|
@@ -573,10 +561,10 @@ var modulesSchema = z15.array(moduleSchema).max(4).describe(
|
|
|
573
561
|
});
|
|
574
562
|
|
|
575
563
|
// src/schema/widget.ts
|
|
576
|
-
var endpointsSchema =
|
|
577
|
-
upload:
|
|
578
|
-
transcribe:
|
|
579
|
-
submitForm:
|
|
564
|
+
var endpointsSchema = z15.object({
|
|
565
|
+
upload: z15.string().min(1).max(2048).default("/ai/agent/upload-file"),
|
|
566
|
+
transcribe: z15.string().min(1).max(2048).default("/ai/agent/transcribe-audio"),
|
|
567
|
+
submitForm: z15.string().min(1).max(2048).default("/ai/agent/submit-form").describe(
|
|
580
568
|
"Form submission endpoint. The widget POSTs each completed form's values here (fire-and-forget), keyed by the same visitorId + conversationId as the conversation; the payload carries `formId` + `trigger` so the backend can route. Optional \u2014 a 404 is ignored."
|
|
581
569
|
)
|
|
582
570
|
}).loose().describe("HTTP endpoint overrides. Paths are appended to baseUrl; absolute URLs are accepted too.").meta({
|
|
@@ -586,14 +574,14 @@ var endpointsSchema = z16.object({
|
|
|
586
574
|
{ submitForm: "https://crm.acme.com/leads" }
|
|
587
575
|
]
|
|
588
576
|
});
|
|
589
|
-
var userContextSchema =
|
|
590
|
-
id:
|
|
591
|
-
email:
|
|
592
|
-
name:
|
|
593
|
-
plan:
|
|
594
|
-
role:
|
|
595
|
-
phone:
|
|
596
|
-
}).catchall(
|
|
577
|
+
var userContextSchema = z15.object({
|
|
578
|
+
id: z15.string().min(1).max(200).optional().describe("Host's stable id for the user \u2014 informational context the agent/backend can key on (not auth)."),
|
|
579
|
+
email: z15.string().min(1).max(320).optional().describe("User email \u2014 surfaced to the agent for context (optional)."),
|
|
580
|
+
name: z15.string().min(1).max(200).optional().describe("Display name \u2014 shown in the Home greeting (`{name}`) and conversation transcripts (optional)."),
|
|
581
|
+
plan: z15.string().min(1).max(120).optional().describe("Subscription / pricing tier, e.g. `pro` (optional)."),
|
|
582
|
+
role: z15.string().min(1).max(120).optional().describe("The user's role on the host site, e.g. `admin` (optional)."),
|
|
583
|
+
phone: z15.string().min(1).max(40).optional().describe("Phone number (optional).")
|
|
584
|
+
}).catchall(z15.union([z15.string(), z15.number(), z15.boolean()])).describe(
|
|
597
585
|
"Host-asserted end-user context (informational, untrusted \u2014 not authentication). Recognised `id` / `email` / `name` / `plan` / `role` / `phone` plus any extra custom scalar fields forwarded to the agent."
|
|
598
586
|
).meta({
|
|
599
587
|
examples: [{ id: "u_123" }, { id: "u_123", email: "alex@acme.com", name: "Alex Lee", plan: "pro" }]
|
|
@@ -609,31 +597,31 @@ var PAGE_AREA_SUGGESTIONS = [
|
|
|
609
597
|
"account",
|
|
610
598
|
"blog"
|
|
611
599
|
];
|
|
612
|
-
var pageContextSchema =
|
|
613
|
-
area:
|
|
614
|
-
url:
|
|
615
|
-
path:
|
|
616
|
-
title:
|
|
617
|
-
}).catchall(
|
|
600
|
+
var pageContextSchema = z15.object({
|
|
601
|
+
area: z15.string().min(1).max(64).optional().describe(`Host-defined surface the visitor is on. Free-form; suggested: ${PAGE_AREA_SUGGESTIONS.join(" | ")}.`),
|
|
602
|
+
url: z15.string().min(1).max(2048).optional().describe("Full page URL. Auto-filled from the host page when omitted."),
|
|
603
|
+
path: z15.string().min(1).max(2048).optional().describe("Page path, e.g. `/pricing/enterprise`."),
|
|
604
|
+
title: z15.string().min(1).max(300).optional().describe("Human-readable page title.")
|
|
605
|
+
}).catchall(z15.union([z15.string(), z15.number(), z15.boolean()])).describe(
|
|
618
606
|
"Host-asserted page/visit context (informational, untrusted). Where the visitor is + the surface (`area`) they're using, plus any custom scalar fields, forwarded to the agent."
|
|
619
607
|
).meta({ examples: [{ area: "pricing", path: "/pricing" }, { area: "help-desk" }] });
|
|
620
|
-
var connectionConfigSchema =
|
|
621
|
-
widgetId:
|
|
608
|
+
var connectionConfigSchema = z15.object({
|
|
609
|
+
widgetId: z15.string().min(1).max(80).default("default").describe(
|
|
622
610
|
"Stable per-instance id used to namespace localStorage keys. Set this when mounting more than one widget on the same page so their conversation state doesn't collide."
|
|
623
611
|
),
|
|
624
|
-
publicKey:
|
|
612
|
+
publicKey: z15.string().min(1).max(200).optional().describe(
|
|
625
613
|
"Workspace-scoped public key (`agent_pk_\u2026`) issued from the dashboard. Sent on every API call as the `x-public-key` header."
|
|
626
614
|
),
|
|
627
|
-
aiAgentDeploymentId:
|
|
615
|
+
aiAgentDeploymentId: z15.string().min(1).max(200).optional().describe(
|
|
628
616
|
"Deployment UUID from the dashboard. Picks which agent / settings bundle answers this mount. Sent as `x-ai-agent-deployment-id`."
|
|
629
617
|
),
|
|
630
|
-
baseUrl:
|
|
618
|
+
baseUrl: z15.string().min(1).max(2048).optional().describe(
|
|
631
619
|
"Full backend origin (e.g. `https://help.ai/api`). Set this to point at your staging / self-hosted / custom backend. Default: the brand's `defaultBaseUrl` baked at build time."
|
|
632
620
|
),
|
|
633
621
|
userContext: userContextSchema.optional(),
|
|
634
622
|
pageContext: pageContextSchema.optional(),
|
|
635
623
|
endpoints: endpointsSchema.optional(),
|
|
636
|
-
debug:
|
|
624
|
+
debug: z15.union([z15.boolean(), z15.enum(["off", "error", "warn", "info", "debug", "trace"])]).optional().describe(
|
|
637
625
|
'Console log verbosity. `false` / `"off"` silences everything (default in production). `true` \u2192 `"debug"`. Levels `error` / `warn` / `info` / `debug` / `trace` gate output additively. Use `"trace"` to capture per-chunk SSE frames + every state transition. Also toggleable at runtime via `chat.setDebug(level)` or `?<brand>-debug=trace` in the page URL \u2014 the URL beats this option, this option beats the persisted `localStorage` value.'
|
|
638
626
|
)
|
|
639
627
|
}).loose().describe(
|
|
@@ -653,14 +641,13 @@ var connectionConfigSchema = z16.object({
|
|
|
653
641
|
}
|
|
654
642
|
]
|
|
655
643
|
});
|
|
656
|
-
var widgetSettingsSchema =
|
|
644
|
+
var widgetSettingsSchema = z15.object({
|
|
657
645
|
presentation: presentationSchema.optional(),
|
|
658
646
|
behavior: behaviorSchema.optional(),
|
|
659
647
|
theme: themeFieldSchema.default("auto").describe("Theme preference (`auto` follows OS) or a tokens override object (`accent`, `radius`, `fontFamily`)."),
|
|
660
648
|
launcher: launcherOptionsSchema.optional(),
|
|
661
649
|
header: headerSchema.optional(),
|
|
662
650
|
composer: composerOptionsSchema.optional(),
|
|
663
|
-
welcome: welcomeOptionsSchema.optional(),
|
|
664
651
|
feedback: feedbackSchema.optional(),
|
|
665
652
|
i18n: i18nSchema.optional(),
|
|
666
653
|
footer: footerSchema.optional(),
|
|
@@ -686,10 +673,10 @@ var widgetSettingsSchema = z16.object({
|
|
|
686
673
|
});
|
|
687
674
|
var widgetConfigSchema = connectionConfigSchema.extend({
|
|
688
675
|
...widgetSettingsSchema.shape,
|
|
689
|
-
site:
|
|
676
|
+
site: z15.unknown().optional().describe(
|
|
690
677
|
'Site config \u2014 applies in `mode: "page"`. Comes from the start-conversation response, not user-edited.'
|
|
691
678
|
),
|
|
692
|
-
blocks:
|
|
679
|
+
blocks: z15.unknown().optional().describe('Blocks (nav + link cards) \u2014 applies in `mode: "page"`. Comes from the start-conversation response.')
|
|
693
680
|
}).describe(
|
|
694
681
|
"Full client widget config \u2014 connection (where + auth) + widget settings (look + behaviour) + page-mode extras. This is what the runtime parses on `mount()` / `init()`. Mode-specific constraints (e.g. `position` only meaningful in `floating`) are NOT enforced here \u2014 the runtime silently ignores irrelevant fields rather than rejecting them so the same object can flow across mode changes."
|
|
695
682
|
).meta({
|
|
@@ -712,49 +699,49 @@ var widgetSettingsPartialSchema = widgetSettingsSchema.partial();
|
|
|
712
699
|
var connectionConfigPartialSchema = connectionConfigSchema.partial();
|
|
713
700
|
|
|
714
701
|
// src/schema/deployment.ts
|
|
715
|
-
import { z as
|
|
702
|
+
import { z as z16 } from "zod";
|
|
716
703
|
var serverConfigSchema = widgetSettingsSchema.partial();
|
|
717
|
-
var siteConfigSchema =
|
|
718
|
-
title:
|
|
704
|
+
var siteConfigSchema = z16.object({
|
|
705
|
+
title: z16.string().min(1).max(120).optional().describe("Brand / site name. Used as the logo's alt-text fallback."),
|
|
719
706
|
logo: assetSchema.optional().describe("Brand logo shown at the top of the page-mode sidebar."),
|
|
720
707
|
logoDark: assetSchema.optional().describe(
|
|
721
708
|
"Optional dark-theme logo variant. Falls back to `logo` when the active theme is light or `logoDark` is unset."
|
|
722
709
|
)
|
|
723
710
|
}).loose();
|
|
724
|
-
var blocksConfigSchema =
|
|
725
|
-
navigation:
|
|
726
|
-
linkCards:
|
|
711
|
+
var blocksConfigSchema = z16.object({
|
|
712
|
+
navigation: z16.array(linkSchema).max(100).optional().describe("Sidebar navigation links (vertical list, primary nav)."),
|
|
713
|
+
linkCards: z16.array(linkSchema).max(100).optional().describe("Sidebar link cards (richer entries with optional `description`).")
|
|
727
714
|
}).loose();
|
|
728
|
-
var handshakeWelcomeMessageSchema =
|
|
729
|
-
id:
|
|
730
|
-
role:
|
|
731
|
-
text:
|
|
715
|
+
var handshakeWelcomeMessageSchema = z16.object({
|
|
716
|
+
id: z16.string(),
|
|
717
|
+
role: z16.enum(["assistant", "system"]),
|
|
718
|
+
text: z16.string()
|
|
732
719
|
}).loose();
|
|
733
|
-
var handshakeWelcomeSuggestionSchema =
|
|
734
|
-
id:
|
|
735
|
-
label:
|
|
736
|
-
text:
|
|
720
|
+
var handshakeWelcomeSuggestionSchema = z16.object({
|
|
721
|
+
id: z16.string(),
|
|
722
|
+
label: z16.string(),
|
|
723
|
+
text: z16.string().optional()
|
|
737
724
|
}).loose();
|
|
738
|
-
var rebindReasonSchema =
|
|
739
|
-
var startConversationResponseSchema =
|
|
740
|
-
deployment:
|
|
741
|
-
id:
|
|
742
|
-
name:
|
|
725
|
+
var rebindReasonSchema = z16.enum(["conflict", "expired", "invalid"]);
|
|
726
|
+
var startConversationResponseSchema = z16.object({
|
|
727
|
+
deployment: z16.object({
|
|
728
|
+
id: z16.string(),
|
|
729
|
+
name: z16.string(),
|
|
743
730
|
// Page URL identifier — present on every deployment; unique per host.
|
|
744
731
|
// Used to mount page deployments via `?slug=…`.
|
|
745
|
-
slug:
|
|
746
|
-
publicKey:
|
|
732
|
+
slug: z16.string().optional(),
|
|
733
|
+
publicKey: z16.string().optional()
|
|
747
734
|
// Deliberately no `type` / `channel` here. Deployment-level
|
|
748
735
|
// taxonomy is a backend categorization concern — the widget's
|
|
749
736
|
// rendering choice flows from `widget.presentation.mode`, not
|
|
750
737
|
// the deployment record's category. `.loose()` lets any such
|
|
751
738
|
// backend field pass through without typing.
|
|
752
739
|
}).loose(),
|
|
753
|
-
agent:
|
|
754
|
-
id:
|
|
755
|
-
name:
|
|
756
|
-
title:
|
|
757
|
-
status:
|
|
740
|
+
agent: z16.object({
|
|
741
|
+
id: z16.string(),
|
|
742
|
+
name: z16.string(),
|
|
743
|
+
title: z16.string().optional(),
|
|
744
|
+
status: z16.enum(["online", "away", "offline"]).optional()
|
|
758
745
|
}).loose(),
|
|
759
746
|
/**
|
|
760
747
|
* Deployment-wide widget configuration the dashboard admin saved
|
|
@@ -764,26 +751,26 @@ var startConversationResponseSchema = z17.object({
|
|
|
764
751
|
config: serverConfigSchema.optional(),
|
|
765
752
|
site: siteConfigSchema.optional(),
|
|
766
753
|
blocks: blocksConfigSchema.optional(),
|
|
767
|
-
welcome:
|
|
768
|
-
messages:
|
|
769
|
-
suggestions:
|
|
754
|
+
welcome: z16.object({
|
|
755
|
+
messages: z16.array(handshakeWelcomeMessageSchema).optional(),
|
|
756
|
+
suggestions: z16.array(handshakeWelcomeSuggestionSchema).optional()
|
|
770
757
|
}).loose().optional(),
|
|
771
|
-
visitorId:
|
|
772
|
-
conversationId:
|
|
773
|
-
canContinue:
|
|
774
|
-
messages:
|
|
758
|
+
visitorId: z16.string(),
|
|
759
|
+
conversationId: z16.string(),
|
|
760
|
+
canContinue: z16.boolean(),
|
|
761
|
+
messages: z16.array(z16.unknown()),
|
|
775
762
|
/**
|
|
776
763
|
* Form submissions recorded for this conversation — echoed like
|
|
777
764
|
* `messages` so the widget reconstructs the collapsed "form submitted"
|
|
778
765
|
* timeline markers on resume. `createdAt` is ISO-8601 (a serialized
|
|
779
766
|
* Mongo ISODate — same format as message `createdAt`).
|
|
780
767
|
*/
|
|
781
|
-
formSubmissions:
|
|
782
|
-
|
|
783
|
-
formId:
|
|
784
|
-
trigger:
|
|
785
|
-
skipped:
|
|
786
|
-
createdAt:
|
|
768
|
+
formSubmissions: z16.array(
|
|
769
|
+
z16.object({
|
|
770
|
+
formId: z16.string(),
|
|
771
|
+
trigger: z16.string(),
|
|
772
|
+
skipped: z16.boolean().optional(),
|
|
773
|
+
createdAt: z16.iso.datetime().optional()
|
|
787
774
|
}).loose()
|
|
788
775
|
).optional(),
|
|
789
776
|
/**
|
|
@@ -792,11 +779,11 @@ var startConversationResponseSchema = z17.object({
|
|
|
792
779
|
* what THIS visitor toggled inside the widget, not the
|
|
793
780
|
* deployment's admin-set defaults.
|
|
794
781
|
*/
|
|
795
|
-
userPrefs:
|
|
782
|
+
userPrefs: z16.record(z16.string(), z16.unknown()).optional(),
|
|
796
783
|
// Present only when the server rotated the request `visitorId` /
|
|
797
784
|
// `conversationId`. Purely advisory — client must adopt the response ids
|
|
798
785
|
// verbatim regardless of whether this block is present.
|
|
799
|
-
rebind:
|
|
786
|
+
rebind: z16.object({
|
|
800
787
|
visitorId: rebindReasonSchema.optional(),
|
|
801
788
|
conversationId: rebindReasonSchema.optional()
|
|
802
789
|
}).loose().optional()
|
|
@@ -806,7 +793,6 @@ var startConversationResponseSchema = z17.object({
|
|
|
806
793
|
import "zod";
|
|
807
794
|
var COMMON_SECTIONS = [
|
|
808
795
|
"theme",
|
|
809
|
-
"welcome",
|
|
810
796
|
"header",
|
|
811
797
|
"composer",
|
|
812
798
|
"footer",
|
|
@@ -833,15 +819,15 @@ function widgetSettingsSchemaForMode(mode) {
|
|
|
833
819
|
var ALL_MODES = ["floating", "inline", "standalone", "page", "modal", "drawer"];
|
|
834
820
|
|
|
835
821
|
// src/schema/json-schema.ts
|
|
836
|
-
import { z as
|
|
822
|
+
import { z as z18 } from "zod";
|
|
837
823
|
function emitJsonSchema() {
|
|
838
824
|
return {
|
|
839
825
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
840
826
|
title: "@helpai/elements config",
|
|
841
827
|
description: "Canonical config schemas for the embeddable AI agent elements widget.",
|
|
842
828
|
definitions: {
|
|
843
|
-
WidgetConfig:
|
|
844
|
-
StartConversationResponse:
|
|
829
|
+
WidgetConfig: z18.toJSONSchema(widgetConfigSchema),
|
|
830
|
+
StartConversationResponse: z18.toJSONSchema(startConversationResponseSchema)
|
|
845
831
|
}
|
|
846
832
|
};
|
|
847
833
|
}
|
|
@@ -912,8 +898,6 @@ export {
|
|
|
912
898
|
userContextSchema,
|
|
913
899
|
uuid7Schema,
|
|
914
900
|
voiceModeSchema,
|
|
915
|
-
welcomeAnimationSchema,
|
|
916
|
-
welcomeOptionsSchema,
|
|
917
901
|
widgetConfigPartialSchema,
|
|
918
902
|
widgetConfigSchema,
|
|
919
903
|
widgetSettingsPartialSchema,
|
package/style.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
:host{--helpai-accent-user: #5B5BD6;--helpai-accent: var(--helpai-accent-user);--helpai-accent-text: #FFFFFF;--helpai-radius: 12px;--helpai-radius-sm: 8px;--helpai-radius-md: 10px;--helpai-radius-lg: 16px;--helpai-font: Inter, system-ui, -apple-system, 'Segoe UI', sans-serif;--helpai-font-display: var(--helpai-font);--helpai-font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;--helpai-bg: oklch(1 0 0);--helpai-bg-elevated: oklch(.9789 .0029 278.3);--helpai-surface: var(--helpai-bg-elevated);--helpai-muted: var(--helpai-fg-muted);--helpai-hover: oklch(.1686 .011 278.3 / .06);--helpai-fg: oklch(.1686 .011 278.3);--helpai-fg-muted: oklch(.4932 .0301 278.3);--helpai-border: oklch(.9312 .0084 278.3);--helpai-border-strong: oklch(.8757 .0131 278.3);--helpai-bubble-user: var(--helpai-accent);--helpai-bubble-user-text: var(--helpai-accent-text);--helpai-bubble-assistant: oklch(.9638 .0058 278.3);--helpai-bubble-assistant-text: var(--helpai-fg);--helpai-on-accent: var(--helpai-accent-text);--helpai-success: oklch(.6456 .1654 151.53);--helpai-warning: oklch(.7135 .1494 74.05);--helpai-danger: oklch(.5966 .1818 24.51);--helpai-danger-text: oklch(.5054 .1905 27.52);--helpai-danger-bg: oklch(.5966 .1818 24.51 / .1);--helpai-neutral: oklch(.7137 .0192 278.3);--helpai-focus: var(--helpai-accent);--helpai-shadow-panel: 0 8px 24px -8px rgba(13, 15, 20, .18), 0 24px 64px -24px rgba(13, 15, 20, .24);--helpai-shadow-card: 0 1px 2px rgba(13, 15, 20, .06), 0 4px 12px -6px rgba(13, 15, 20, .12);--helpai-backdrop: oklch(.1686 .011 278.3 / .55);--helpai-shadow-fab: 0 6px 16px -4px color-mix(in oklch, var(--helpai-accent) 45%, transparent), 0 12px 32px -12px rgba(13, 15, 20, .25);--helpai-z-fab: 2147483600;--helpai-z-panel: 2147483601;--helpai-panel-w: 380px;--helpai-panel-h: 600px;--helpai-fab-size: 56px;--helpai-space-1: 4px;--helpai-space-2: 8px;--helpai-space-3: 12px;--helpai-space-4: 16px;--helpai-space-5: 20px;--helpai-space-6: 24px;--helpai-space-8: 32px;--helpai-text-scale: 1;--helpai-text-xs: calc(12px * var(--helpai-text-scale));--helpai-text-sm: calc(13px * var(--helpai-text-scale));--helpai-text-base: calc(15px * var(--helpai-text-scale));--helpai-text-md: calc(16px * var(--helpai-text-scale));--helpai-text-lg: calc(18px * var(--helpai-text-scale));--helpai-text-xl: calc(22px * var(--helpai-text-scale));--helpai-text-2xl: calc(30px * var(--helpai-text-scale))}:host([data-text-size="small"]){--helpai-text-scale: .9}:host([data-text-size="large"]){--helpai-text-scale: 1.15}:host{--helpai-ease: cubic-bezier(.2, .7, .2, 1);--helpai-ease-out: cubic-bezier(.2, .7, .2, 1);--helpai-ease-in: cubic-bezier(.4, 0, 1, 1);--helpai-ease-in-out: cubic-bezier(.65, 0, .35, 1);--helpai-dur-quick: .12s;--helpai-dur-base: .22s;--helpai-dur-slow: .32s;font-family:var(--helpai-font);color:var(--helpai-fg);color-scheme:light;--helpai-color-scheme: light}:host([data-theme="dark"]){--helpai-bg: oklch(.1783 .0128 278.3);--helpai-bg-elevated: oklch(.2232 .0182 278.3);--helpai-fg: oklch(.9368 .01 278.3);--helpai-fg-muted: oklch(.7048 .0296 278.3);--helpai-border: oklch(.2752 .0266 278.3);--helpai-border-strong: oklch(.335 .0291 278.3);--helpai-hover: oklch(.9368 .01 278.3 / .08);--helpai-bubble-assistant: oklch(.2474 .0311 278.3);--helpai-bubble-assistant-text: var(--helpai-fg);--helpai-danger-text: oklch(.8077 .1035 19.57);--helpai-danger-bg: oklch(.5966 .1818 24.51 / .18);--helpai-shadow-panel: 0 8px 24px -8px rgba(0, 0, 0, .6), 0 24px 64px -24px rgba(0, 0, 0, .7);--helpai-shadow-card: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 12px -6px rgba(0, 0, 0, .5);--helpai-backdrop: rgba(0, 0, 0, .65);color-scheme:dark;--helpai-color-scheme: dark}@media(prefers-color-scheme:dark){:host([data-theme="auto"]){--helpai-bg: oklch(.1783 .0128 278.3);--helpai-bg-elevated: oklch(.2232 .0182 278.3);--helpai-fg: oklch(.9368 .01 278.3);--helpai-fg-muted: oklch(.7048 .0296 278.3);--helpai-border: oklch(.2752 .0266 278.3);--helpai-border-strong: oklch(.335 .0291 278.3);--helpai-hover: oklch(.9368 .01 278.3 / .08);--helpai-bubble-assistant: oklch(.2474 .0311 278.3);--helpai-bubble-assistant-text: var(--helpai-fg);--helpai-shadow-panel: 0 8px 24px -8px rgba(0, 0, 0, .6), 0 24px 64px -24px rgba(0, 0, 0, .7);color-scheme:dark;--helpai-color-scheme: dark}}@supports (color: oklch(from red l c h)){:host{--helpai-accent: oklch(from var(--helpai-accent-user) clamp(.3, l, .62) c h);--helpai-accent-text: oklch(from var(--helpai-accent) clamp(0, (l / .623 - 1) * -infinity, 1) 0 h)}:host([data-theme="dark"]){--helpai-accent: oklch(from var(--helpai-accent-user) clamp(.65, l, .85) c h)}@media(prefers-color-scheme:dark){:host([data-theme="auto"]){--helpai-accent: oklch(from var(--helpai-accent-user) clamp(.65, l, .85) c h)}}}@media(prefers-reduced-motion:reduce){:host{--helpai-dur-quick: 1ms;--helpai-dur-base: 1ms;--helpai-dur-slow: 1ms}}
|
|
1
|
+
:host{--helpai-accent-user: #5B5BD6;--helpai-accent: var(--helpai-accent-user);--helpai-accent-text-user: #FFFFFF;--helpai-accent-text: var(--helpai-accent-text-user);--helpai-radius: 12px;--helpai-radius-sm: 8px;--helpai-radius-md: 10px;--helpai-radius-lg: 16px;--helpai-font: Inter, system-ui, -apple-system, 'Segoe UI', sans-serif;--helpai-font-display: var(--helpai-font);--helpai-font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;--helpai-bg: oklch(1 0 0);--helpai-bg-elevated: oklch(.9789 .0029 278.3);--helpai-surface: var(--helpai-bg-elevated);--helpai-muted: var(--helpai-fg-muted);--helpai-hover: oklch(.1686 .011 278.3 / .06);--helpai-fg: oklch(.1686 .011 278.3);--helpai-fg-muted: oklch(.4932 .0301 278.3);--helpai-border: oklch(.9312 .0084 278.3);--helpai-border-strong: oklch(.8757 .0131 278.3);--helpai-bubble-user: var(--helpai-accent);--helpai-bubble-user-text: var(--helpai-accent-text);--helpai-bubble-assistant: oklch(.9638 .0058 278.3);--helpai-bubble-assistant-text: var(--helpai-fg);--helpai-on-accent: var(--helpai-accent-text);--helpai-success: oklch(.6456 .1654 151.53);--helpai-warning: oklch(.7135 .1494 74.05);--helpai-danger: oklch(.5966 .1818 24.51);--helpai-danger-text: oklch(.5054 .1905 27.52);--helpai-danger-bg: oklch(.5966 .1818 24.51 / .1);--helpai-neutral: oklch(.7137 .0192 278.3);--helpai-focus: var(--helpai-accent);--helpai-shadow-panel: 0 8px 24px -8px rgba(13, 15, 20, .18), 0 24px 64px -24px rgba(13, 15, 20, .24);--helpai-shadow-card: 0 1px 2px rgba(13, 15, 20, .06), 0 4px 12px -6px rgba(13, 15, 20, .12);--helpai-backdrop: oklch(.1686 .011 278.3 / .55);--helpai-shadow-fab: 0 6px 16px -4px color-mix(in oklch, var(--helpai-accent) 45%, transparent), 0 12px 32px -12px rgba(13, 15, 20, .25);--helpai-z-fab: 2147483600;--helpai-z-panel: 2147483601;--helpai-panel-w: 380px;--helpai-panel-h: 600px;--helpai-fab-size: 56px;--helpai-space-1: 4px;--helpai-space-2: 8px;--helpai-space-3: 12px;--helpai-space-4: 16px;--helpai-space-5: 20px;--helpai-space-6: 24px;--helpai-space-8: 32px;--helpai-text-scale: 1;--helpai-text-xs: calc(12px * var(--helpai-text-scale));--helpai-text-sm: calc(13px * var(--helpai-text-scale));--helpai-text-base: calc(15px * var(--helpai-text-scale));--helpai-text-md: calc(16px * var(--helpai-text-scale));--helpai-text-lg: calc(18px * var(--helpai-text-scale));--helpai-text-xl: calc(22px * var(--helpai-text-scale));--helpai-text-2xl: calc(30px * var(--helpai-text-scale))}:host([data-text-size="small"]){--helpai-text-scale: .9}:host([data-text-size="large"]){--helpai-text-scale: 1.15}:host{--helpai-ease: cubic-bezier(.2, .7, .2, 1);--helpai-ease-out: cubic-bezier(.2, .7, .2, 1);--helpai-ease-in: cubic-bezier(.4, 0, 1, 1);--helpai-ease-in-out: cubic-bezier(.65, 0, .35, 1);--helpai-dur-quick: .12s;--helpai-dur-base: .22s;--helpai-dur-slow: .32s;font-family:var(--helpai-font);color:var(--helpai-fg);color-scheme:light;--helpai-color-scheme: light}:host([data-theme="dark"]){--helpai-bg: oklch(.1783 .0128 278.3);--helpai-bg-elevated: oklch(.2232 .0182 278.3);--helpai-fg: oklch(.9368 .01 278.3);--helpai-fg-muted: oklch(.7048 .0296 278.3);--helpai-border: oklch(.2752 .0266 278.3);--helpai-border-strong: oklch(.335 .0291 278.3);--helpai-hover: oklch(.9368 .01 278.3 / .08);--helpai-bubble-assistant: oklch(.2474 .0311 278.3);--helpai-bubble-assistant-text: var(--helpai-fg);--helpai-danger-text: oklch(.8077 .1035 19.57);--helpai-danger-bg: oklch(.5966 .1818 24.51 / .18);--helpai-shadow-panel: 0 8px 24px -8px rgba(0, 0, 0, .6), 0 24px 64px -24px rgba(0, 0, 0, .7);--helpai-shadow-card: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 12px -6px rgba(0, 0, 0, .5);--helpai-backdrop: rgba(0, 0, 0, .65);color-scheme:dark;--helpai-color-scheme: dark}@media(prefers-color-scheme:dark){:host([data-theme="auto"]){--helpai-bg: oklch(.1783 .0128 278.3);--helpai-bg-elevated: oklch(.2232 .0182 278.3);--helpai-fg: oklch(.9368 .01 278.3);--helpai-fg-muted: oklch(.7048 .0296 278.3);--helpai-border: oklch(.2752 .0266 278.3);--helpai-border-strong: oklch(.335 .0291 278.3);--helpai-hover: oklch(.9368 .01 278.3 / .08);--helpai-bubble-assistant: oklch(.2474 .0311 278.3);--helpai-bubble-assistant-text: var(--helpai-fg);--helpai-shadow-panel: 0 8px 24px -8px rgba(0, 0, 0, .6), 0 24px 64px -24px rgba(0, 0, 0, .7);color-scheme:dark;--helpai-color-scheme: dark}}@supports (color: oklch(from red l c h)){:host{--helpai-accent: oklch(from var(--helpai-accent-user) clamp(.3, l, .62) c h);--helpai-accent-text: oklch(from var(--helpai-accent) clamp(0, (l / .623 - 1) * -infinity, 1) 0 h)}:host([data-theme="dark"]){--helpai-accent: oklch(from var(--helpai-accent-user) clamp(.65, l, .85) c h)}@media(prefers-color-scheme:dark){:host([data-theme="auto"]){--helpai-accent: oklch(from var(--helpai-accent-user) clamp(.65, l, .85) c h)}}}@media(prefers-reduced-motion:reduce){:host{--helpai-dur-quick: 1ms;--helpai-dur-base: 1ms;--helpai-dur-slow: 1ms}}
|
|
2
2
|
|
|
3
3
|
*,*: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(--helpai-accent);outline-offset:2px}textarea,input{font:inherit;color:inherit;background:none;border:0;outline:0;resize:none}a{color:var(--helpai-accent);text-decoration:underline;text-underline-offset:2px}img,svg{display:block;max-width:100%}ul,ol{list-style:none}.helpai-app{display:block;width:100%;height:100%;font-family:var(--helpai-font);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-feature-settings:"cv11","ss01","ss03"}.helpai-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}
|
|
4
4
|
|