@helpai/elements 0.24.0 → 0.26.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/README.md CHANGED
@@ -85,7 +85,7 @@ re-resolves at runtime.
85
85
  | `index.mjs` / `web-component.mjs` | ESM | Bundlers (Vite, webpack, esbuild) — bare imports kept |
86
86
  | `elements.cjs.js` | CJS | `require()` from Node / legacy tooling |
87
87
  | `style.css` | CSS | `<link rel="stylesheet">` |
88
- | `schema.json` | JSON Schema | Dashboard config UIs, backend start-conversation validation, 3rd-party tooling |
88
+ | `schema.json` | JSON Schema | Dashboard config UIs, backend handshake validation, 3rd-party tooling |
89
89
  | `schema.mjs` | ESM | Zod runtime schemas: `import { widgetConfigSchema } from "@helpai/elements/schema"` |
90
90
 
91
91
  Every bundle exposes the same surface (`mount`, `init`, `hook`, types).
@@ -323,7 +323,7 @@ attribute. See [https://help.ai/docs/elements/modes](https://help.ai/docs/elemen
323
323
  ## Configuration
324
324
 
325
325
  The element reads its per-deployment configuration from your
326
- Help AI workspace at start-conversation time — colors, launcher
326
+ Help AI workspace at handshake time — colors, launcher
327
327
  chrome, strings, action layout, model defaults, history visibility
328
328
  all flow through `StartConversationResponse.settings`. You don't recompile
329
329
  per-customer.
@@ -335,7 +335,7 @@ mount({
335
335
  publicKey: "agent_pk_...",
336
336
  aiAgentDeploymentId: "...",
337
337
  presentation: { mode: "floating" },
338
- baseUrl: "https://help.ai/api", // omit to use the brand default
338
+ baseUrl: "https://help.ai", // omit to use the brand default
339
339
  user: { id: "u_123", email: "alice@help.ai" },
340
340
  theme: "dark", // "auto" | "light" | "dark" | overrides object
341
341
  i18n: { defaultLocale: "en" },
package/configurator.mjs CHANGED
@@ -132,7 +132,7 @@ var behaviorSchema = z4.object({
132
132
  "Show tool/function calls the model makes (e.g. search) as inline chips in the transcript. `false` (default) hides them."
133
133
  ),
134
134
  popOutUrl: z4.string().min(1).max(2048).optional().describe(
135
- "URL the `popOut` action opens in a new tab (carries `?conversation=<id>&widgetId=<id>` query params). Falls back to the brand's build-time default. Set this to point at your own dedicated chat page (e.g. `https://app.acme.com/chat`). Server-pushable on `/start-conversation.widget.behavior.popOutUrl`."
135
+ "URL the `popOut` action opens in a new tab (carries `?conversation=<id>&widgetId=<id>` query params). Falls back to the brand's build-time default. Set this to point at your own dedicated chat page (e.g. `https://app.acme.com/chat`). Server-pushable on `/handshake.widget.behavior.popOutUrl`."
136
136
  )
137
137
  }).loose().describe("Lifecycle + streaming behaviour. Doesn't affect visual presentation.").meta({
138
138
  examples: [
@@ -520,7 +520,7 @@ var moduleSchema = z14.object({
520
520
  "UI layout that renders this tab: `chat` (the conversation), `home`, `help`, or `news`."
521
521
  ),
522
522
  contentTags: z14.array(z14.string().max(60)).max(20).optional().describe(
523
- "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."
523
+ "Content tags this tab scopes to \u2014 the `tags` filter on `GET /content` (matches content tagged with ANY of them). Omit for the `chat` layout."
524
524
  ),
525
525
  id: z14.string().max(60).optional().describe(
526
526
  "Stable id for navigation + last-tab persistence. Defaults to the first `contentTags` entry, else `layout`."
@@ -573,10 +573,12 @@ var modulesSchema = z14.array(moduleSchema).max(4).describe(
573
573
  import { z as z15 } from "zod";
574
574
  var trackingSchema = z15.object({
575
575
  enabled: z15.boolean().optional().describe("Master switch. Default `false` \u2014 no hits are sent until the deployment turns tracking on."),
576
- 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."),
576
+ endpoint: z15.url().max(2048).optional().describe(
577
+ "Pixel collector URL. Default: `${dataBaseUrl}/elements/px.gif` (e.g. `https://help.ai/api/data/elements/px.gif`). Must be a full URL."
578
+ ),
577
579
  sampleRate: z15.number().min(0).max(1).optional().describe("Per-visitor sampling 0..1 (decided once per page load, keeping funnels intact). Default `1`."),
578
580
  token: z15.string().max(512).optional().describe(
579
- "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`)."
581
+ "Anti-forgery token, echoed as `tk=` on every hit. Server-issued in the `/handshake` response \u2014 never set by hand (see `docs/api/tracking-collector.md`)."
580
582
  )
581
583
  }).loose().describe(
582
584
  "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."
@@ -586,14 +588,16 @@ var trackingSchema = z15.object({
586
588
 
587
589
  // src/schema/widget.ts
588
590
  var endpointsSchema = z16.object({
589
- upload: z16.string().min(1).max(2048).default("/ai/agent/upload-file"),
590
- transcribe: z16.string().min(1).max(2048).default("/ai/agent/transcribe-audio"),
591
- submitForm: z16.string().min(1).max(2048).default("/ai/agent/submit-form").describe(
591
+ upload: z16.string().min(1).max(2048).default("/ai-agent/upload-file"),
592
+ transcribe: z16.string().min(1).max(2048).default("/ai-agent/transcribe-audio"),
593
+ submitForm: z16.string().min(1).max(2048).default("/submit-form").describe(
592
594
  "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."
593
595
  )
594
- }).loose().describe("HTTP endpoint overrides. Paths are appended to baseUrl; absolute URLs are accepted too.").meta({
596
+ }).loose().describe(
597
+ "HTTP endpoint overrides. `upload` / `transcribe` paths are appended to the agent base (`${baseUrl}/api/agent`), `submitForm` to the data base (`dataBaseUrl`); absolute URLs are accepted too."
598
+ ).meta({
595
599
  examples: [
596
- { upload: "/ai/agent/upload-file", transcribe: "/ai/agent/transcribe-audio" },
600
+ { upload: "/ai-agent/upload-file", transcribe: "/ai-agent/transcribe-audio" },
597
601
  { upload: "https://help.ai/uploads/presign" },
598
602
  { submitForm: "https://crm.acme.com/leads" }
599
603
  ]
@@ -640,7 +644,13 @@ var connectionConfigSchema = z16.object({
640
644
  "Deployment UUID from the dashboard. Picks which agent / settings bundle answers this mount. Sent as `x-ai-agent-deployment-id`."
641
645
  ),
642
646
  baseUrl: z16.string().min(1).max(2048).optional().describe(
643
- "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."
647
+ "MAIN site origin (e.g. `https://help.ai`) \u2014 the API modules derive from it: agent API at `${baseUrl}/api/agent`, data API at `${baseUrl}/api/data`. Set this to point at your staging / self-hosted / custom backend. Default: the brand's `defaultBaseUrl` baked at build time."
648
+ ),
649
+ agentBaseUrl: z16.string().min(1).max(2048).optional().describe(
650
+ "Full agent-API base \u2014 set it to reach a STANDALONE `module-help-ai-agent-api` directly (local module on its own port, e.g. `http://localhost:3087`; routes attach as-is: `/ai-agent/handshake`). Precedence: this option > derived from the main origin (`${baseUrl}/api/agent`). Not server-pushable."
651
+ ),
652
+ dataBaseUrl: z16.string().min(1).max(2048).optional().describe(
653
+ "Full data-API base (e.g. `https://help.ai/api/data`, or a standalone local module like `http://localhost:3106`) \u2014 the service serving content, form definitions (`GET /forms`), and form submissions at root-level paths. Precedence: this option > server-pushed `config.dataBaseUrl` > derived from the main origin (`${baseUrl}/api/data`)."
644
654
  ),
645
655
  userContext: userContextSchema.optional(),
646
656
  pageContext: pageContextSchema.optional(),
@@ -680,7 +690,7 @@ var widgetSettingsSchema = z16.object({
680
690
  modules: modulesSchema.optional(),
681
691
  tracking: trackingSchema.optional()
682
692
  }).loose().describe(
683
- "Portal-configurable widget settings \u2014 fourteen sections, one per dashboard tab. The backend pushes this same shape on `/ai/agent/start-conversation` under `config`."
693
+ "Portal-configurable widget settings \u2014 fourteen sections, one per dashboard tab. The backend pushes this same shape on `/ai-agent/handshake` under `config`."
684
694
  ).meta({
685
695
  examples: [
686
696
  { presentation: { mode: "floating", position: "bottom-right" }, theme: "auto" },
@@ -698,10 +708,8 @@ var widgetSettingsSchema = z16.object({
698
708
  });
699
709
  var widgetConfigSchema = connectionConfigSchema.extend({
700
710
  ...widgetSettingsSchema.shape,
701
- site: z16.unknown().optional().describe(
702
- 'Site config \u2014 applies in `mode: "page"`. Comes from the start-conversation response, not user-edited.'
703
- ),
704
- blocks: z16.unknown().optional().describe('Blocks (nav + link cards) \u2014 applies in `mode: "page"`. Comes from the start-conversation response.')
711
+ site: z16.unknown().optional().describe('Site config \u2014 applies in `mode: "page"`. Comes from the handshake response, not user-edited.'),
712
+ blocks: z16.unknown().optional().describe('Blocks (nav + link cards) \u2014 applies in `mode: "page"`. Comes from the handshake response.')
705
713
  }).describe(
706
714
  "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."
707
715
  ).meta({
@@ -725,7 +733,9 @@ var connectionConfigPartialSchema = connectionConfigSchema.partial();
725
733
 
726
734
  // src/schema/deployment.ts
727
735
  import { z as z17 } from "zod";
728
- var serverConfigSchema = widgetSettingsSchema.partial();
736
+ var serverConfigSchema = widgetSettingsSchema.partial().omit({ forms: true }).extend({
737
+ dataBaseUrl: z17.string().min(1).max(2048).optional()
738
+ });
729
739
  var siteConfigSchema = z17.object({
730
740
  title: z17.string().min(1).max(120).optional().describe("Brand / site name. Used as the logo's alt-text fallback."),
731
741
  logo: assetSchema.optional().describe("Brand logo shown at the top of the page-mode sidebar."),
@@ -748,7 +758,7 @@ var handshakeWelcomeSuggestionSchema = z17.object({
748
758
  text: z17.string().optional()
749
759
  }).loose();
750
760
  var rebindReasonSchema = z17.enum(["conflict", "expired", "invalid"]);
751
- var startConversationResponseSchema = z17.object({
761
+ var handshakeResponseSchema = z17.object({
752
762
  deployment: z17.object({
753
763
  id: z17.string(),
754
764
  name: z17.string(),
@@ -782,22 +792,6 @@ var startConversationResponseSchema = z17.object({
782
792
  }).loose().optional(),
783
793
  visitorId: z17.string(),
784
794
  conversationId: z17.string(),
785
- canContinue: z17.boolean(),
786
- messages: z17.array(z17.unknown()),
787
- /**
788
- * Form submissions recorded for this conversation — echoed like
789
- * `messages` so the widget reconstructs the collapsed "form submitted"
790
- * timeline markers on resume. `createdAt` is ISO-8601 (a serialized
791
- * Mongo ISODate — same format as message `createdAt`).
792
- */
793
- formSubmissions: z17.array(
794
- z17.object({
795
- formId: z17.string(),
796
- trigger: z17.string(),
797
- skipped: z17.boolean().optional(),
798
- createdAt: z17.iso.datetime().optional()
799
- }).loose()
800
- ).optional(),
801
795
  /**
802
796
  * Per-visitor preferences (locale picker, theme picker, sound
803
797
  * mute, dragged panel size). Distinct from `config` — this is