@helpai/elements 0.21.1 → 0.23.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 +88 -72
- package/elements-web-component.esm.js +26 -26
- package/elements-web-component.esm.js.map +3 -3
- package/elements.cjs.js +26 -26
- package/elements.cjs.js.map +4 -4
- package/elements.esm.js +26 -26
- package/elements.esm.js.map +4 -4
- package/elements.js +26 -26
- package/elements.js.map +4 -4
- package/index.d.ts +64 -5
- package/index.mjs +208 -19
- package/package.json +1 -1
- package/schema.d.ts +67 -50
- package/schema.json +74 -0
- package/schema.mjs +93 -75
- package/style.css +1 -1
- package/web-component.mjs +89 -19
package/configurator.mjs
CHANGED
|
@@ -20,7 +20,7 @@ var localeSchema = z.string().min(1).max(35).describe("BCP-47 locale tag (e.g. `
|
|
|
20
20
|
var uuid7Schema = z.uuidv7().describe("UUID v7 (RFC 9562) \u2014 the single id format for visitor / conversation / message / file / content ids.");
|
|
21
21
|
|
|
22
22
|
// src/schema/widget.ts
|
|
23
|
-
import { z as
|
|
23
|
+
import { z as z16 } from "zod";
|
|
24
24
|
|
|
25
25
|
// src/schema/widget/presentation.ts
|
|
26
26
|
import { z as z3 } from "zod";
|
|
@@ -563,11 +563,26 @@ var modulesSchema = z14.array(moduleSchema).max(4).describe(
|
|
|
563
563
|
]
|
|
564
564
|
});
|
|
565
565
|
|
|
566
|
+
// src/schema/widget/tracking.ts
|
|
567
|
+
import { z as z15 } from "zod";
|
|
568
|
+
var trackingSchema = z15.object({
|
|
569
|
+
enabled: z15.boolean().optional().describe("Master switch. Default `false` \u2014 no hits are sent until the deployment turns tracking on."),
|
|
570
|
+
endpoint: z15.url().max(2048).optional().describe("Pixel collector URL. Default: `https://t.<brand domain>/api/ai-elements/px.gif`. Must be a full URL."),
|
|
571
|
+
sampleRate: z15.number().min(0).max(1).optional().describe("Per-visitor sampling 0..1 (decided once per page load, keeping funnels intact). Default `1`."),
|
|
572
|
+
token: z15.string().max(512).optional().describe(
|
|
573
|
+
"Anti-forgery token, echoed as `tk=` on every hit. Server-issued in the `/start-conversation` response \u2014 never set by hand (see `docs/api/tracking-collector.md`)."
|
|
574
|
+
)
|
|
575
|
+
}).loose().describe(
|
|
576
|
+
"Anonymous usage tracking for the widget owner \u2014 GA-style pixel events (open, send, form submit, \u2026) with page / device / locale dimensions. Never includes message content; visitors are identified only by the widget's anonymous visitorId."
|
|
577
|
+
).meta({
|
|
578
|
+
examples: [{ enabled: true }, { enabled: true, sampleRate: 0.5 }]
|
|
579
|
+
});
|
|
580
|
+
|
|
566
581
|
// src/schema/widget.ts
|
|
567
|
-
var endpointsSchema =
|
|
568
|
-
upload:
|
|
569
|
-
transcribe:
|
|
570
|
-
submitForm:
|
|
582
|
+
var endpointsSchema = z16.object({
|
|
583
|
+
upload: z16.string().min(1).max(2048).default("/ai/agent/upload-file"),
|
|
584
|
+
transcribe: z16.string().min(1).max(2048).default("/ai/agent/transcribe-audio"),
|
|
585
|
+
submitForm: z16.string().min(1).max(2048).default("/ai/agent/submit-form").describe(
|
|
571
586
|
"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."
|
|
572
587
|
)
|
|
573
588
|
}).loose().describe("HTTP endpoint overrides. Paths are appended to baseUrl; absolute URLs are accepted too.").meta({
|
|
@@ -577,14 +592,14 @@ var endpointsSchema = z15.object({
|
|
|
577
592
|
{ submitForm: "https://crm.acme.com/leads" }
|
|
578
593
|
]
|
|
579
594
|
});
|
|
580
|
-
var userContextSchema =
|
|
581
|
-
id:
|
|
582
|
-
email:
|
|
583
|
-
name:
|
|
584
|
-
plan:
|
|
585
|
-
role:
|
|
586
|
-
phone:
|
|
587
|
-
}).catchall(
|
|
595
|
+
var userContextSchema = z16.object({
|
|
596
|
+
id: z16.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)."),
|
|
597
|
+
email: z16.string().min(1).max(320).optional().describe("User email \u2014 surfaced to the agent for context (optional)."),
|
|
598
|
+
name: z16.string().min(1).max(200).optional().describe("Display name \u2014 shown in the Home greeting (`{name}`) and conversation transcripts (optional)."),
|
|
599
|
+
plan: z16.string().min(1).max(120).optional().describe("Subscription / pricing tier, e.g. `pro` (optional)."),
|
|
600
|
+
role: z16.string().min(1).max(120).optional().describe("The user's role on the host site, e.g. `admin` (optional)."),
|
|
601
|
+
phone: z16.string().min(1).max(40).optional().describe("Phone number (optional).")
|
|
602
|
+
}).catchall(z16.union([z16.string(), z16.number(), z16.boolean()])).describe(
|
|
588
603
|
"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."
|
|
589
604
|
).meta({
|
|
590
605
|
examples: [{ id: "u_123" }, { id: "u_123", email: "alex@acme.com", name: "Alex Lee", plan: "pro" }]
|
|
@@ -600,31 +615,31 @@ var PAGE_AREA_SUGGESTIONS = [
|
|
|
600
615
|
"account",
|
|
601
616
|
"blog"
|
|
602
617
|
];
|
|
603
|
-
var pageContextSchema =
|
|
604
|
-
area:
|
|
605
|
-
url:
|
|
606
|
-
path:
|
|
607
|
-
title:
|
|
608
|
-
}).catchall(
|
|
618
|
+
var pageContextSchema = z16.object({
|
|
619
|
+
area: z16.string().min(1).max(64).optional().describe(`Host-defined surface the visitor is on. Free-form; suggested: ${PAGE_AREA_SUGGESTIONS.join(" | ")}.`),
|
|
620
|
+
url: z16.string().min(1).max(2048).optional().describe("Full page URL. Auto-filled from the host page when omitted."),
|
|
621
|
+
path: z16.string().min(1).max(2048).optional().describe("Page path, e.g. `/pricing/enterprise`."),
|
|
622
|
+
title: z16.string().min(1).max(300).optional().describe("Human-readable page title.")
|
|
623
|
+
}).catchall(z16.union([z16.string(), z16.number(), z16.boolean()])).describe(
|
|
609
624
|
"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."
|
|
610
625
|
).meta({ examples: [{ area: "pricing", path: "/pricing" }, { area: "help-desk" }] });
|
|
611
|
-
var connectionConfigSchema =
|
|
612
|
-
widgetId:
|
|
626
|
+
var connectionConfigSchema = z16.object({
|
|
627
|
+
widgetId: z16.string().min(1).max(80).default("default").describe(
|
|
613
628
|
"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."
|
|
614
629
|
),
|
|
615
|
-
publicKey:
|
|
630
|
+
publicKey: z16.string().min(1).max(200).optional().describe(
|
|
616
631
|
"Workspace-scoped public key (`agent_pk_\u2026`) issued from the dashboard. Sent on every API call as the `x-public-key` header."
|
|
617
632
|
),
|
|
618
|
-
aiAgentDeploymentId:
|
|
633
|
+
aiAgentDeploymentId: z16.string().min(1).max(200).optional().describe(
|
|
619
634
|
"Deployment UUID from the dashboard. Picks which agent / settings bundle answers this mount. Sent as `x-ai-agent-deployment-id`."
|
|
620
635
|
),
|
|
621
|
-
baseUrl:
|
|
636
|
+
baseUrl: z16.string().min(1).max(2048).optional().describe(
|
|
622
637
|
"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."
|
|
623
638
|
),
|
|
624
639
|
userContext: userContextSchema.optional(),
|
|
625
640
|
pageContext: pageContextSchema.optional(),
|
|
626
641
|
endpoints: endpointsSchema.optional(),
|
|
627
|
-
debug:
|
|
642
|
+
debug: z16.union([z16.boolean(), z16.enum(["off", "error", "warn", "info", "debug", "trace"])]).optional().describe(
|
|
628
643
|
'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.'
|
|
629
644
|
)
|
|
630
645
|
}).loose().describe(
|
|
@@ -644,7 +659,7 @@ var connectionConfigSchema = z15.object({
|
|
|
644
659
|
}
|
|
645
660
|
]
|
|
646
661
|
});
|
|
647
|
-
var widgetSettingsSchema =
|
|
662
|
+
var widgetSettingsSchema = z16.object({
|
|
648
663
|
presentation: presentationSchema.optional(),
|
|
649
664
|
behavior: behaviorSchema.optional(),
|
|
650
665
|
theme: themeFieldSchema.default("auto").describe("Theme preference (`auto` follows OS) or a tokens override object (`accent`, `radius`, `fontFamily`)."),
|
|
@@ -656,9 +671,10 @@ var widgetSettingsSchema = z15.object({
|
|
|
656
671
|
footer: footerSchema.optional(),
|
|
657
672
|
features: featureFlagsSchema.optional(),
|
|
658
673
|
forms: formsSchema.optional(),
|
|
659
|
-
modules: modulesSchema.optional()
|
|
674
|
+
modules: modulesSchema.optional(),
|
|
675
|
+
tracking: trackingSchema.optional()
|
|
660
676
|
}).loose().describe(
|
|
661
|
-
"Portal-configurable widget settings \u2014
|
|
677
|
+
"Portal-configurable widget settings \u2014 fourteen sections, one per dashboard tab. The backend pushes this same shape on `/ai/agent/start-conversation` under `config`."
|
|
662
678
|
).meta({
|
|
663
679
|
examples: [
|
|
664
680
|
{ presentation: { mode: "floating", position: "bottom-right" }, theme: "auto" },
|
|
@@ -676,10 +692,10 @@ var widgetSettingsSchema = z15.object({
|
|
|
676
692
|
});
|
|
677
693
|
var widgetConfigSchema = connectionConfigSchema.extend({
|
|
678
694
|
...widgetSettingsSchema.shape,
|
|
679
|
-
site:
|
|
695
|
+
site: z16.unknown().optional().describe(
|
|
680
696
|
'Site config \u2014 applies in `mode: "page"`. Comes from the start-conversation response, not user-edited.'
|
|
681
697
|
),
|
|
682
|
-
blocks:
|
|
698
|
+
blocks: z16.unknown().optional().describe('Blocks (nav + link cards) \u2014 applies in `mode: "page"`. Comes from the start-conversation response.')
|
|
683
699
|
}).describe(
|
|
684
700
|
"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."
|
|
685
701
|
).meta({
|
|
@@ -702,49 +718,49 @@ var widgetSettingsPartialSchema = widgetSettingsSchema.partial();
|
|
|
702
718
|
var connectionConfigPartialSchema = connectionConfigSchema.partial();
|
|
703
719
|
|
|
704
720
|
// src/schema/deployment.ts
|
|
705
|
-
import { z as
|
|
721
|
+
import { z as z17 } from "zod";
|
|
706
722
|
var serverConfigSchema = widgetSettingsSchema.partial();
|
|
707
|
-
var siteConfigSchema =
|
|
708
|
-
title:
|
|
723
|
+
var siteConfigSchema = z17.object({
|
|
724
|
+
title: z17.string().min(1).max(120).optional().describe("Brand / site name. Used as the logo's alt-text fallback."),
|
|
709
725
|
logo: assetSchema.optional().describe("Brand logo shown at the top of the page-mode sidebar."),
|
|
710
726
|
logoDark: assetSchema.optional().describe(
|
|
711
727
|
"Optional dark-theme logo variant. Falls back to `logo` when the active theme is light or `logoDark` is unset."
|
|
712
728
|
)
|
|
713
729
|
}).loose();
|
|
714
|
-
var blocksConfigSchema =
|
|
715
|
-
navigation:
|
|
716
|
-
linkCards:
|
|
730
|
+
var blocksConfigSchema = z17.object({
|
|
731
|
+
navigation: z17.array(linkSchema).max(100).optional().describe("Sidebar navigation links (vertical list, primary nav)."),
|
|
732
|
+
linkCards: z17.array(linkSchema).max(100).optional().describe("Sidebar link cards (richer entries with optional `description`).")
|
|
717
733
|
}).loose();
|
|
718
|
-
var handshakeWelcomeMessageSchema =
|
|
719
|
-
id:
|
|
720
|
-
role:
|
|
721
|
-
text:
|
|
734
|
+
var handshakeWelcomeMessageSchema = z17.object({
|
|
735
|
+
id: z17.string(),
|
|
736
|
+
role: z17.enum(["assistant", "system"]),
|
|
737
|
+
text: z17.string()
|
|
722
738
|
}).loose();
|
|
723
|
-
var handshakeWelcomeSuggestionSchema =
|
|
724
|
-
id:
|
|
725
|
-
label:
|
|
726
|
-
text:
|
|
739
|
+
var handshakeWelcomeSuggestionSchema = z17.object({
|
|
740
|
+
id: z17.string(),
|
|
741
|
+
label: z17.string(),
|
|
742
|
+
text: z17.string().optional()
|
|
727
743
|
}).loose();
|
|
728
|
-
var rebindReasonSchema =
|
|
729
|
-
var startConversationResponseSchema =
|
|
730
|
-
deployment:
|
|
731
|
-
id:
|
|
732
|
-
name:
|
|
744
|
+
var rebindReasonSchema = z17.enum(["conflict", "expired", "invalid"]);
|
|
745
|
+
var startConversationResponseSchema = z17.object({
|
|
746
|
+
deployment: z17.object({
|
|
747
|
+
id: z17.string(),
|
|
748
|
+
name: z17.string(),
|
|
733
749
|
// Page URL identifier — present on every deployment; unique per host.
|
|
734
750
|
// Used to mount page deployments via `?slug=…`.
|
|
735
|
-
slug:
|
|
736
|
-
publicKey:
|
|
751
|
+
slug: z17.string().optional(),
|
|
752
|
+
publicKey: z17.string().optional()
|
|
737
753
|
// Deliberately no `type` / `channel` here. Deployment-level
|
|
738
754
|
// taxonomy is a backend categorization concern — the widget's
|
|
739
755
|
// rendering choice flows from `widget.presentation.mode`, not
|
|
740
756
|
// the deployment record's category. `.loose()` lets any such
|
|
741
757
|
// backend field pass through without typing.
|
|
742
758
|
}).loose(),
|
|
743
|
-
agent:
|
|
744
|
-
id:
|
|
745
|
-
name:
|
|
746
|
-
title:
|
|
747
|
-
status:
|
|
759
|
+
agent: z17.object({
|
|
760
|
+
id: z17.string(),
|
|
761
|
+
name: z17.string(),
|
|
762
|
+
title: z17.string().optional(),
|
|
763
|
+
status: z17.enum(["online", "away", "offline"]).optional()
|
|
748
764
|
}).loose(),
|
|
749
765
|
/**
|
|
750
766
|
* Deployment-wide widget configuration the dashboard admin saved
|
|
@@ -754,26 +770,26 @@ var startConversationResponseSchema = z16.object({
|
|
|
754
770
|
config: serverConfigSchema.optional(),
|
|
755
771
|
site: siteConfigSchema.optional(),
|
|
756
772
|
blocks: blocksConfigSchema.optional(),
|
|
757
|
-
welcome:
|
|
758
|
-
messages:
|
|
759
|
-
suggestions:
|
|
773
|
+
welcome: z17.object({
|
|
774
|
+
messages: z17.array(handshakeWelcomeMessageSchema).optional(),
|
|
775
|
+
suggestions: z17.array(handshakeWelcomeSuggestionSchema).optional()
|
|
760
776
|
}).loose().optional(),
|
|
761
|
-
visitorId:
|
|
762
|
-
conversationId:
|
|
763
|
-
canContinue:
|
|
764
|
-
messages:
|
|
777
|
+
visitorId: z17.string(),
|
|
778
|
+
conversationId: z17.string(),
|
|
779
|
+
canContinue: z17.boolean(),
|
|
780
|
+
messages: z17.array(z17.unknown()),
|
|
765
781
|
/**
|
|
766
782
|
* Form submissions recorded for this conversation — echoed like
|
|
767
783
|
* `messages` so the widget reconstructs the collapsed "form submitted"
|
|
768
784
|
* timeline markers on resume. `createdAt` is ISO-8601 (a serialized
|
|
769
785
|
* Mongo ISODate — same format as message `createdAt`).
|
|
770
786
|
*/
|
|
771
|
-
formSubmissions:
|
|
772
|
-
|
|
773
|
-
formId:
|
|
774
|
-
trigger:
|
|
775
|
-
skipped:
|
|
776
|
-
createdAt:
|
|
787
|
+
formSubmissions: z17.array(
|
|
788
|
+
z17.object({
|
|
789
|
+
formId: z17.string(),
|
|
790
|
+
trigger: z17.string(),
|
|
791
|
+
skipped: z17.boolean().optional(),
|
|
792
|
+
createdAt: z17.iso.datetime().optional()
|
|
777
793
|
}).loose()
|
|
778
794
|
).optional(),
|
|
779
795
|
/**
|
|
@@ -782,11 +798,11 @@ var startConversationResponseSchema = z16.object({
|
|
|
782
798
|
* what THIS visitor toggled inside the widget, not the
|
|
783
799
|
* deployment's admin-set defaults.
|
|
784
800
|
*/
|
|
785
|
-
userPrefs:
|
|
801
|
+
userPrefs: z17.record(z17.string(), z17.unknown()).optional(),
|
|
786
802
|
// Present only when the server rotated the request `visitorId` /
|
|
787
803
|
// `conversationId`. Purely advisory — client must adopt the response ids
|
|
788
804
|
// verbatim regardless of whether this block is present.
|
|
789
|
-
rebind:
|
|
805
|
+
rebind: z17.object({
|
|
790
806
|
visitorId: rebindReasonSchema.optional(),
|
|
791
807
|
conversationId: rebindReasonSchema.optional()
|
|
792
808
|
}).loose().optional()
|
|
@@ -796,7 +812,7 @@ var startConversationResponseSchema = z16.object({
|
|
|
796
812
|
import "zod";
|
|
797
813
|
|
|
798
814
|
// src/schema/json-schema.ts
|
|
799
|
-
import { z as
|
|
815
|
+
import { z as z19 } from "zod";
|
|
800
816
|
|
|
801
817
|
// src/configurator/field-help.tsx
|
|
802
818
|
import { createPortal } from "preact/compat";
|