@helpai/elements 1.10.0 → 1.12.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/llms-full.txt CHANGED
@@ -1,6 +1,6 @@
1
- # Help AI Elements: the full SDK docs (@helpai/elements@1.10.0)
1
+ # Help AI Elements: the full SDK docs (@helpai/elements@1.12.0)
2
2
 
3
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/quickstart.md -->
3
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/quickstart.md -->
4
4
 
5
5
  # Quickstart
6
6
 
@@ -67,7 +67,7 @@ kebab-case `data-*` attribute. Common ones:
67
67
  ></script>
68
68
  ```
69
69
 
70
- Full list: [Installation § script data attributes](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/installation.md#path-a--script-data--auto-boot).
70
+ Full list: [Installation § script data attributes](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md#path-a--script-data--auto-boot).
71
71
 
72
72
  ---
73
73
 
@@ -149,7 +149,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
149
149
  ### Vue / Svelte / Angular / any bundler
150
150
 
151
151
  Call `init(...)` once on mount and `destroy()` on unmount, or use the `<web-ai-chat>` element (path D).
152
- Full framework-by-framework walkthrough: [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md).
152
+ Full framework-by-framework walkthrough: [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md).
153
153
 
154
154
  ---
155
155
 
@@ -186,20 +186,20 @@ round chat bubble with an accent color.
186
186
  - **Close the panel** → the bubble returns.
187
187
  - **Reload the page** → your chat history stays intact.
188
188
 
189
- Something not showing up? → [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/troubleshooting.md).
189
+ Something not showing up? → [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/troubleshooting.md).
190
190
 
191
191
  ---
192
192
 
193
193
  ## 4. Common next steps
194
194
 
195
- - **Match your brand** — [Theming](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md) has every color,
195
+ - **Match your brand** — [Theming](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md) has every color,
196
196
  radius, and font knob.
197
- - **Change the launcher label / icon** — [`launcher` options](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md#launcher).
197
+ - **Change the launcher label / icon** — [`launcher` options](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md#launcher).
198
198
  - **Know who the visitor is** — pass `userContext: { id, email, name }`
199
199
  (and `pageContext: { area }`) for personalization.
200
- - **Forward chat events to analytics** — [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md).
200
+ - **Forward chat events to analytics** — [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md).
201
201
  - **Add a second widget** (one for sales, one for support) — [Recipes
202
- § Multiple widgets](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#multiple-widgets-on-one-page).
202
+ § Multiple widgets](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#multiple-widgets-on-one-page).
203
203
 
204
204
  ---
205
205
 
@@ -230,15 +230,15 @@ the same deployment:
230
230
  | Remix | read from `window.ENV` |
231
231
  | Create React App | `REACT_APP_*` |
232
232
 
233
- Full security notes: [Security & privacy](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md).
233
+ Full security notes: [Security & privacy](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md).
234
234
 
235
235
  ---
236
236
 
237
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/installation.md -->
237
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md -->
238
238
 
239
239
  # Installation
240
240
 
241
- Deep-dive for every install path. See [Quickstart](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/quickstart.md)
241
+ Deep-dive for every install path. See [Quickstart](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/quickstart.md)
242
242
  for the 5-minute version.
243
243
 
244
244
  ---
@@ -250,7 +250,7 @@ for the 5-minute version.
250
250
  | [A. `<script data-*>` auto-boot](#path-a--script-data--auto-boot) | Static HTML, WordPress, no build step | CDN |
251
251
  | [B. Async loader snippet](#path-b--async-loader-snippet) | Tag managers, analytics pipelines | CDN |
252
252
  | [C. NPM package](#path-c--npm-package) | React, Next.js, Vue, Svelte, SolidJS, any bundler | NPM |
253
- | [React kit](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md#react) | React, Next.js, Remix: `<HelpAI />` + `useHelpAI()` | NPM |
253
+ | [React kit](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md#react) | React, Next.js, Remix: `<HelpAI />` + `useHelpAI()` | NPM |
254
254
  | [D. Web Component](#path-d--web-component) | Declarative tags in any framework | CDN or NPM |
255
255
 
256
256
  > ### CDN URL
@@ -271,9 +271,9 @@ for the 5-minute version.
271
271
  All four paths:
272
272
 
273
273
  - Load the same JS bundle.
274
- - Accept the same [configuration options](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md).
275
- - Emit the same [events](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md).
276
- - Respect the same [isolation guarantees](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#shadow-dom--iframe).
274
+ - Accept the same [configuration options](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md).
275
+ - Emit the same [events](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md).
276
+ - Respect the same [isolation guarantees](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#shadow-dom--iframe).
277
277
 
278
278
  You can combine them — e.g., a Next.js page can use path C, and a
279
279
  marketing landing can use path A, both pointing at the same deployment.
@@ -327,24 +327,24 @@ The zero-JavaScript path intentionally exposes a small, flat subset of
327
327
  | `data-page-context` | `pageContext` extras (JSON) | `'{"experiment":"b"}'` |
328
328
 
329
329
  Unknown attributes are ignored. Full option semantics:
330
- [Configuration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md).
330
+ [Configuration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md).
331
331
 
332
332
  > Explicit scalar attributes (`data-user-id`, `data-page-area`, …) win
333
333
  > over keys in the `data-user-context` / `data-page-context` JSON. For
334
334
  > SPAs where the visitor logs in after load or navigates between pages,
335
335
  > set context dynamically with
336
- > [`instance.setUserContext(...)` / `setPageContext(...)`](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md#setting-context-after-login--on-navigation).
336
+ > [`instance.setUserContext(...)` / `setPageContext(...)`](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md#setting-context-after-login--on-navigation).
337
337
  > The `data-user-*` / `data-page-*` attributes are reactive — updating
338
338
  > one re-handshakes with the same anonymous visitor/conversation. This
339
339
  > context is informational for the AI, never an auth credential.
340
340
 
341
- ### `data-no-autoboot`
341
+ ### Load without mounting
342
342
 
343
- Add this flag to load the bundle **without** automatically mounting.
344
- Useful when you want to `init()` later from JavaScript:
343
+ The script tag mounts the widget only when it carries `data-ai-agent-deployment-id`. Leave that attribute out to
344
+ load the bundle **without** mounting, then call `init()` from JavaScript when you're ready:
345
345
 
346
346
  ```html
347
- <script src="https://cdn.help.ai/sdk/js/elements/latest/elements.js" data-no-autoboot></script>
347
+ <script src="https://cdn.help.ai/sdk/js/elements/latest/elements.js"></script>
348
348
  <script>
349
349
  // Mount later, conditionally
350
350
  document.addEventListener('DOMContentLoaded', () => {
@@ -436,7 +436,7 @@ arrays or objects to it before the bundle arrives:
436
436
  </script>
437
437
  ```
438
438
 
439
- Full details: [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md#global-lifecycle-hooks).
439
+ Full details: [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md#global-lifecycle-hooks).
440
440
 
441
441
  ### After boot
442
442
 
@@ -458,7 +458,7 @@ window.HelpAI.brand // { id, displayName, cdnUrl, ... }
458
458
  ## Path C — NPM package
459
459
 
460
460
  For sites with a bundler. Full framework-specific walkthroughs:
461
- [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md).
461
+ [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md).
462
462
 
463
463
  ### Install
464
464
 
@@ -650,7 +650,7 @@ declare module 'react' {
650
650
 
651
651
  **Angular** — add `CUSTOM_ELEMENTS_SCHEMA` to your module.
652
652
 
653
- Framework-by-framework details: [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md).
653
+ Framework-by-framework details: [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md).
654
654
 
655
655
  ---
656
656
 
@@ -858,14 +858,14 @@ weigh chunking (see [Caching, versioning & self-hosting](#caching-versioning--se
858
858
 
859
859
  ## Next
860
860
 
861
- - [Configuration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md) — every option explained with examples.
862
- - [Theming & customization](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md) — matching your brand.
863
- - [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md) — framework-specific recipes.
864
- - [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/troubleshooting.md) — "my widget isn't showing up".
861
+ - [Configuration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md) — every option explained with examples.
862
+ - [Theming & customization](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md) — matching your brand.
863
+ - [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md) — framework-specific recipes.
864
+ - [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/troubleshooting.md) — "my widget isn't showing up".
865
865
 
866
866
  ---
867
867
 
868
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md -->
868
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md -->
869
869
 
870
870
  # Framework integrations
871
871
 
@@ -954,20 +954,23 @@ function PricingHelp() {
954
954
  }
955
955
  ```
956
956
 
957
- - **`<HelpAI {...options} />`** takes every [widget option](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md) as a prop; `aiAgentDeploymentId` is
957
+ - **`<HelpAI {...options} />`** takes every [widget option](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md) as a prop; `aiAgentDeploymentId` is
958
958
  required. It renders nothing itself: the widget mounts once the page is in the browser, a prop change re-configures
959
959
  the live widget without a remount, and unmounting removes it. Callback props (`onOpen`, `onMessage`, …) can be new
960
960
  functions on every render; the widget always calls the latest one.
961
- - **`useHelpAI(widgetId?)`** returns `{ state, ask, open, close, reset }`. `state` is
962
- [`{ open, ready, unread, conversationId? }`](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/api-reference.md#state-and-ready) and re-renders the component when it changes;
961
+ - **`useHelpAI(widgetId?)`** returns `{ state, ask, open, close, reset, track }`. `state` is
962
+ [`{ open, ready, unread, conversationId? }`](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/api-reference.md#state-and-ready) and re-renders the component when it changes;
963
963
  the server render sees the initial state. The commands are stable across renders and do nothing until the widget
964
964
  has mounted (`state.ready`). `ask(text)` fills the composer; `ask(text, { send: true })` sends it. Call `reset()`
965
965
  when your user logs out.
966
966
  - **One import path.** The kit carries the whole widget API (`getInstance`, `hook`, the types), so import everything
967
967
  from `@helpai/elements/react`; the package's other entries are separate copies with their own widgets.
968
968
  - **Two widgets** on one page: give each `<HelpAI widgetId='support' … />` and read it with `useHelpAI('support')`.
969
+ - **Page tools:** `useHelpAITool(tool)` gives the agent a tool while the component is mounted, or pass
970
+ `<HelpAI tools={[...]} />` ([Page tools](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/page-tools.md)). `execute` can be a new function on every render; the
971
+ agent's call runs the latest one, and only a changed definition registers or configures anything again.
969
972
  - **Signed-in users:** pass `userToken`, a function that fetches the token your server signs
970
- ([Verified users](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#verified-users-usertoken)). Keep it stable for one user (a module function, or
973
+ ([Verified users](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#verified-users-usertoken)). Keep it stable for one user (a module function, or
971
974
  `useCallback` keyed on your user id): a different function signs in afresh, and dropping it signs out.
972
975
 
973
976
  The kit bundles the widget and imports only React from your app, so you don't need Preact installed.
@@ -990,7 +993,7 @@ function Chat() {
990
993
  `import type {} from '@helpai/elements/jsx/react';` once (in your entry file or a `.d.ts`) registers `<web-ai-chat>`
991
994
  in React 19's JSX: every attribute the element reads autocompletes, `ai-agent-deployment-id` is required, and a `ref`
992
995
  is the typed element with `ask`, `open`, `state`, `ready` and `reset`. Vue and Svelte have `@helpai/elements/jsx/vue`
993
- and `@helpai/elements/jsx/svelte` ([JSX typings](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/api-reference.md#jsx-typings)).
996
+ and `@helpai/elements/jsx/svelte` ([JSX typings](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/api-reference.md#jsx-typings)).
994
997
 
995
998
  ```tsx
996
999
  import { useRef } from 'react';
@@ -1499,21 +1502,21 @@ sometimes mounts duplicate instances. Always pair your `useEffect` /
1499
1502
 
1500
1503
  **CSP blocks the widget** — the widget inlines styles inside a shadow
1501
1504
  root (requires `style-src 'unsafe-inline'` or a nonce pattern). See
1502
- [Security & privacy § CSP](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#content-security-policy).
1505
+ [Security & privacy § CSP](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#content-security-policy).
1503
1506
 
1504
- More: [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/troubleshooting.md).
1507
+ More: [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/troubleshooting.md).
1505
1508
 
1506
1509
  ---
1507
1510
 
1508
1511
  ## Next
1509
1512
 
1510
- - [Recipes](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md) — programmatic control patterns.
1511
- - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md) — analytics integration.
1512
- - [Configuration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md) — every option in detail.
1513
+ - [Recipes](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md) — programmatic control patterns.
1514
+ - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md) — analytics integration.
1515
+ - [Configuration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md) — every option in detail.
1513
1516
 
1514
1517
  ---
1515
1518
 
1516
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md -->
1519
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md -->
1517
1520
 
1518
1521
  # Configuration reference
1519
1522
 
@@ -1521,7 +1524,7 @@ Every option you can pass to `init(...)` / `mount(...)` / set via
1521
1524
  `data-*` attributes / set via web-component attributes.
1522
1525
 
1523
1526
  Group-by-group walkthrough with realistic examples. For an at-a-glance
1524
- lookup, see [API reference](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/api-reference.md).
1527
+ lookup, see [API reference](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/api-reference.md).
1525
1528
 
1526
1529
  ---
1527
1530
 
@@ -1606,7 +1609,7 @@ init({ widgetId: 'support', publicKey: SUPPORT_KEY, aiAgentDeploymentId: SUPPORT
1606
1609
  init({ widgetId: 'sales', publicKey: SALES_KEY, aiAgentDeploymentId: SALES_DEPLOYMENT_ID });
1607
1610
  ```
1608
1611
 
1609
- See [Recipes § Multiple widgets](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#multiple-widgets-on-one-page).
1612
+ See [Recipes § Multiple widgets](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#multiple-widgets-on-one-page).
1610
1613
 
1611
1614
  ### `baseUrl`
1612
1615
 
@@ -1626,12 +1629,30 @@ Override if you use:
1626
1629
  Signs the visitor in as your logged-in user: a JWT your server signs with the deployment's secret key, or a function
1627
1630
  returning a fresh one. Their conversations then follow them to any device, and the AI gets their name and email as
1628
1631
  verified facts. Runtime-only: not an attribute or `data-*` option, so the token stays out of the page's markup. See
1629
- [Security → Verified users](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#verified-users-usertoken) for signing it.
1632
+ [Security → Verified users](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#verified-users-usertoken) for signing it.
1630
1633
 
1631
1634
  ```ts
1632
1635
  init({ publicKey: 'agent_pk_...', aiAgentDeploymentId: '01900000-0000-7000-8000-000000000000', userToken: () => fetch('/api/help-ai-token').then((res) => res.text()) });
1633
1636
  ```
1634
1637
 
1638
+ ### `tools`
1639
+
1640
+ `ModelContextTool[]` · default: none
1641
+
1642
+ Tools the AI agent can use on your page, in the WebMCP tool shape: a name, a description, a JSON Schema of its input
1643
+ and an `execute` function the widget runs in the visitor's browser when the agent calls it
1644
+ (`annotations: { consequentialHint: true }` asks the visitor first). Runtime-only, like `userToken`;
1645
+ `chat.update({ tools })` replaces them. `chat.registerTool(tool)` adds one for every widget on the page instead. Full
1646
+ guide: [Page tools](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/page-tools.md).
1647
+
1648
+ ```ts
1649
+ init({
1650
+ publicKey: 'agent_pk_...',
1651
+ aiAgentDeploymentId: '01900000-0000-7000-8000-000000000000',
1652
+ tools: [{ name: 'open_booking', description: 'Open the booking form. Use it whenever the visitor wants to book a call.', execute: () => (bookingForm.open(), { opened: true }) }],
1653
+ });
1654
+ ```
1655
+
1635
1656
  ### `userContext`
1636
1657
 
1637
1658
  `object | undefined`
@@ -1751,8 +1772,8 @@ widget.clearUserContext();
1751
1772
  ```
1752
1773
 
1753
1774
  You can also seed context at load time via `data-user-*` /
1754
- `data-page-*` tag attributes — see [Installation](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/installation.md) and
1755
- the framework recipes in [`frameworks.md`](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md).
1775
+ `data-page-*` tag attributes — see [Installation](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md) and
1776
+ the framework recipes in [`frameworks.md`](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md).
1756
1777
 
1757
1778
  ---
1758
1779
 
@@ -1807,7 +1828,7 @@ init({ presentation: { mode: 'floating', iframe: true }, publicKey: 'agent_pk_..
1807
1828
  ```
1808
1829
 
1809
1830
  Composes with any `mode`. Default is `false` — shadow DOM alone is
1810
- enough for 95% of deployments. [Security § Iframe isolation](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#iframe-isolation).
1831
+ enough for 95% of deployments. [Security § Iframe isolation](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#iframe-isolation).
1811
1832
 
1812
1833
  ### `presentation.position`
1813
1834
 
@@ -1872,7 +1893,7 @@ mode via the header picker regardless of palette overrides.
1872
1893
  End users can flip the theme via the header picker. Their choice is
1873
1894
  persisted per device + synced cross-device.
1874
1895
 
1875
- Full customization guide: [Theming](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md).
1896
+ Full customization guide: [Theming](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md).
1876
1897
 
1877
1898
  ---
1878
1899
 
@@ -1972,7 +1993,7 @@ init({
1972
1993
  ```
1973
1994
 
1974
1995
  Variants + callout fully explained in
1975
- [Theming § Launcher](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md#launcher).
1996
+ [Theming § Launcher](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md#launcher).
1976
1997
 
1977
1998
  ### `launcher.hidden`
1978
1999
 
@@ -2211,7 +2232,7 @@ Full behavior + wire contract:
2211
2232
  `boolean` · default: `false`
2212
2233
 
2213
2234
  Turn OFF the 👍/👎 feedback controls under each rateable reply (AI or operator) — unset/`false` shows them (default). While
2214
- shown, a choice fires the [`messageFeedback`](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md) event and is sent to the backend.
2235
+ shown, a choice fires the [`messageFeedback`](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md) event and is sent to the backend.
2215
2236
 
2216
2237
  ```ts
2217
2238
  init({ behavior: { disableMessageFeedback: true } }); // hide the controls
@@ -2300,7 +2321,7 @@ init({
2300
2321
  });
2301
2322
  ```
2302
2323
 
2303
- Full key list: [i18n](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md#internationalization) or
2324
+ Full key list: [i18n](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md#internationalization) or
2304
2325
  `src/i18n/strings.ts` in the source.
2305
2326
 
2306
2327
  ---
@@ -2383,7 +2404,7 @@ init({
2383
2404
  });
2384
2405
  ```
2385
2406
 
2386
- For richer event handling, see [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md).
2407
+ For richer event handling, see [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md).
2387
2408
 
2388
2409
  ---
2389
2410
 
@@ -2419,7 +2440,7 @@ The widget itself does not include drafts in Help AI network requests before
2419
2440
  Send. Use an encrypted adapter when same-origin plaintext storage is not
2420
2441
  acceptable; an in-memory adapter disables reload restoration.
2421
2442
 
2422
- Full adapter contract: [Security & privacy § custom storage](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#custom-storage).
2443
+ Full adapter contract: [Security & privacy § custom storage](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#custom-storage).
2423
2444
 
2424
2445
  ---
2425
2446
 
@@ -2525,14 +2546,14 @@ const chat = init({
2525
2546
 
2526
2547
  ## Not covered here
2527
2548
 
2528
- - **Events** → [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md)
2529
- - **Theming deep-dive** → [Theming](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md)
2530
- - **Framework-specific wiring** → [Frameworks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md)
2549
+ - **Events** → [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md)
2550
+ - **Theming deep-dive** → [Theming](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md)
2551
+ - **Framework-specific wiring** → [Frameworks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md)
2531
2552
  - **Backend API** → Backend contract (internal)
2532
2553
 
2533
2554
  ---
2534
2555
 
2535
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/options.md -->
2556
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/options.md -->
2536
2557
 
2537
2558
  # Configuration — `ChatWidgetOptions`
2538
2559
 
@@ -2860,13 +2881,13 @@ Pass `footer: { poweredBy: { text: "" } }` to opt out of the brand attribution.
2860
2881
 
2861
2882
  ---
2862
2883
 
2863
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/api-reference.md -->
2884
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/api-reference.md -->
2864
2885
 
2865
2886
  # API reference
2866
2887
 
2867
2888
  Compact lookup for the SDK's exported functions, types, and events.
2868
- For explanations + examples, see the [Configuration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md)
2869
- and [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md) guides.
2889
+ For explanations + examples, see the [Configuration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md)
2890
+ and [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md) guides.
2870
2891
 
2871
2892
  ---
2872
2893
 
@@ -2910,13 +2931,14 @@ React kit (React 18+; everything above plus the component and the hook, so impor
2910
2931
  ```ts
2911
2932
  import {
2912
2933
  HelpAI, // <HelpAI {...options} /> mounts the widget, re-configures it on prop changes, removes it on unmount
2913
- useHelpAI, // useHelpAI(widgetId?) → { state, ask, open, close, reset }, re-rendering on state changes
2934
+ useHelpAI, // useHelpAI(widgetId?) → { state, ask, open, close, reset, track }, re-rendering on state changes
2935
+ useHelpAITool, // useHelpAITool(tool) gives the agent a page tool while the component is mounted
2914
2936
  type HelpAIProps,
2915
2937
  type HelpAIControls,
2916
2938
  } from '@helpai/elements/react';
2917
2939
  ```
2918
2940
 
2919
- See [Frameworks → React](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md#react).
2941
+ See [Frameworks → React](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md#react).
2920
2942
 
2921
2943
  ---
2922
2944
 
@@ -3004,13 +3026,15 @@ interface ChatWidgetInstance {
3004
3026
  // Lifecycle
3005
3027
  reset(): void; // start over as a new anonymous visitor (on logout)
3006
3028
  login(userToken: UserTokenSource): void; // sign the visitor in as your logged-in user (a signed token, or a function returning one)
3029
+ track(name: string, data?: Record<string, string | number | boolean>): void; // report your page's own event: analytics + the agent's next message
3030
+ registerTool(tool: ModelContextTool, options?: { signal?: AbortSignal }): void; // a tool the agent can use on this page, for every widget on it
3007
3031
  destroy(): void;
3008
3032
 
3009
3033
  // Events
3010
3034
  on<E extends EventName>(name: E, fn: (payload: EventMap[E]) => void): () => void; // returns unsubscribe fn
3011
3035
 
3012
3036
  // Re-config
3013
- update(patch: Partial<ChatWidgetOptions>): void;
3037
+ update(patch: Partial<ChatWidgetOptions>): void; // e.g. update({ tools }) on a route change
3014
3038
 
3015
3039
  // Host-asserted context (informational, not auth; re-handshakes, same visitor/conversation)
3016
3040
  setUserContext(ctx: Partial<NonNullable<ChatWidgetOptions['userContext']>>): void; // merges into the current user context
@@ -3030,7 +3054,7 @@ interface ChatWidgetInstance {
3030
3054
  ## `ChatWidgetOptions`
3031
3055
 
3032
3056
  The generated, schema-backed field reference is
3033
- [`docs/api/configuration.md`](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/options.md); it is authoritative.
3057
+ [`docs/api/configuration.md`](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/options.md); it is authoritative.
3034
3058
  The public input keeps embed identity, context, endpoint overrides, storage,
3035
3059
  and callbacks at the top level. Serializable widget settings use focused
3036
3060
  nested sections. `mount()` and `init()` require `aiAgentDeploymentId`; the
@@ -3070,7 +3094,30 @@ init({
3070
3094
  ```
3071
3095
 
3072
3096
  The complete type also exposes `features`, `forms`, `modules`, and `tracking`.
3073
- See [Configuration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md) for behavior and examples.
3097
+ See [Configuration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md) for behavior and examples.
3098
+
3099
+ ### `ModelContextTool`
3100
+
3101
+ A tool the agent can use on your page, in the WebMCP tool shape ([Page tools](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/page-tools.md)). On `<web-ai-chat>`
3102
+ it's the `tools` property or `registerTool()`, since functions can't be attributes.
3103
+
3104
+ ```ts
3105
+ interface ModelContextTool<TInput = unknown> {
3106
+ name: string; // letters, digits, `_` and `-` (58 at most; others become `_`); the agent sees `site__<name>`
3107
+ title?: string;
3108
+ description: string; // when to use it (1024 characters at most)
3109
+ inputSchema?: Record<string, unknown>; // JSON Schema of an object; none = no input
3110
+ annotations?: ToolAnnotations; // `consequentialHint: true` = the visitor approves each call first
3111
+ execute(input: TInput, options: { signal: AbortSignal }): unknown; // a JSON result, or throw; `signal` aborts when the visitor moves on
3112
+ }
3113
+
3114
+ interface ToolAnnotations {
3115
+ readOnlyHint?: boolean;
3116
+ untrustedContentHint?: boolean;
3117
+ consequentialHint?: boolean;
3118
+ debugging?: boolean;
3119
+ }
3120
+ ```
3074
3121
 
3075
3122
  ### `ActionName`
3076
3123
 
@@ -3205,7 +3252,7 @@ reconnects as that user: their conversations on this browser move to them, and t
3205
3252
  device where they're signed in. Call `reset()` when they sign out; switching to another user's token starts over the
3206
3253
  same way. Also `HelpAI('login', userToken)`, `element.login(userToken)` on `<web-ai-chat>` (not an attribute, so the
3207
3254
  token stays out of the DOM), the `userToken` option at `init()`, and `<HelpAI userToken={…} />`. Signing and the
3208
- guarantees: [Security → Verified users](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#verified-users-usertoken).
3255
+ guarantees: [Security → Verified users](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#verified-users-usertoken).
3209
3256
 
3210
3257
  ```ts
3211
3258
  chat.login(() => fetch('/api/help-ai-token').then((res) => res.text()));
@@ -3213,6 +3260,32 @@ chat.login(() => fetch('/api/help-ai-token').then((res) => res.text()));
3213
3260
 
3214
3261
  ---
3215
3262
 
3263
+ ### `registerTool(tool, options?)`
3264
+
3265
+ Gives the agent a tool on this page, for every widget on it: the latest registration of a name wins, and aborting
3266
+ `options.signal` removes it. Also `HelpAI('registerTool', tool)` (queued before the script loads),
3267
+ `element.registerTool(tool)` and the React kit's `useHelpAITool(tool)`. Details: [Page tools](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/page-tools.md).
3268
+
3269
+ ```ts
3270
+ chat.registerTool({ name: 'open_booking', description: 'Open the booking form. Use it whenever the visitor wants to book a call.', execute: () => bookingForm.open() });
3271
+ ```
3272
+
3273
+ ---
3274
+
3275
+ ### `track(name, data?)`
3276
+
3277
+ Reports something the visitor did on your site, outside the chat. It sends a `hostEvent` hit to Elements analytics
3278
+ (not when tracking is off), and the widget keeps the last 10 for the agent, which reads them with the visitor's next
3279
+ message. The name is 1–64 characters; the data is flat (strings, numbers, booleans; 256 characters of JSON at most).
3280
+ Also `HelpAI('track', name, data)`, `element.track(name, data)` and `useHelpAI().track`. Details:
3281
+ [Analytics → Your own events](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/analytics.md#your-own-events-chattrack).
3282
+
3283
+ ```ts
3284
+ chat.track('plan_viewed', { plan: 'pro' });
3285
+ ```
3286
+
3287
+ ---
3288
+
3216
3289
  ## Events
3217
3290
 
3218
3291
  ### `EventMap`
@@ -3288,10 +3361,10 @@ The auto-boot parser exposes the documented flat `data-*` subset.
3288
3361
  ></script>
3289
3362
  ```
3290
3363
 
3291
- Full attribute list: [Installation § script data attributes](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/installation.md#attributes).
3364
+ Full attribute list: [Installation § script data attributes](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md#attributes).
3292
3365
 
3293
- `data-no-autoboot` — loads the bundle but doesn't auto-mount. For
3294
- deferred init via JS.
3366
+ Leave out `data-ai-agent-deployment-id` to load the bundle without mounting, then call
3367
+ `HelpAI.init({ … })` from JavaScript ([Installation § Load without mounting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md#load-without-mounting)).
3295
3368
 
3296
3369
  ---
3297
3370
 
@@ -3495,14 +3568,14 @@ Or use `/v1/` for the latest 1.x.x (auto-patches, no major breaks).
3495
3568
 
3496
3569
  ## See also
3497
3570
 
3498
- - [Configuration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md) — options with examples + context.
3499
- - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md) — event handling deep-dive.
3500
- - [Recipes](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md) — copy-paste scenarios.
3501
- - [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/troubleshooting.md) — when things go wrong.
3571
+ - [Configuration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md) — options with examples + context.
3572
+ - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md) — event handling deep-dive.
3573
+ - [Recipes](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md) — copy-paste scenarios.
3574
+ - [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/troubleshooting.md) — when things go wrong.
3502
3575
 
3503
3576
  ---
3504
3577
 
3505
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md -->
3578
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md -->
3506
3579
 
3507
3580
  # Events & lifecycle hooks
3508
3581
 
@@ -3524,17 +3597,19 @@ Both deliver the same event stream. Both are safe to mix.
3524
3597
 
3525
3598
  ## Available events
3526
3599
 
3527
- | Event | Fires on | Payload |
3528
- | ----------------- | ------------------------------------------------- | ------------------------------------------------------ |
3529
- | `open` | Panel opens (floating mode) | `void` |
3530
- | `close` | Panel closes | `void` |
3531
- | `message` | User sends a message + assistant finishes a reply | `{ role: "user" \| "assistant"; text: string }` |
3532
- | `error` | Transport error or mid-stream error | `unknown` (error object or message) |
3533
- | `expand` | Expanded tier toggled (⤢) | `boolean` (new state) |
3534
- | `fullscreen` | Fullscreen tier toggled (⛶) | `boolean` (new state) |
3535
- | `handshake` | Widget finishes booting (once per mount) | `HandshakeResponse` (dashboard config) |
3536
- | `localeChange` | User picks a different language | `string` (new BCP-47 tag) |
3537
- | `messageFeedback` | User rates a reply 👍/👎 (or clears it) | `{ messageId: string; value: "up" \| "down" \| null }` |
3600
+ | Event | Fires on | Payload |
3601
+ | ----------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
3602
+ | `open` | Panel opens (floating mode) | `void` |
3603
+ | `close` | Panel closes | `void` |
3604
+ | `message` | User sends a message, or a reply from the AI agent or a team member finishes | `{ role: "user" \| "assistant" \| "operator"; text: string }` |
3605
+ | `error` | Transport error or mid-stream error | `unknown` (error object or message) |
3606
+ | `expand` | Expanded tier toggled (⤢) | `boolean` (new state) |
3607
+ | `fullscreen` | Fullscreen tier toggled (⛶) | `boolean` (new state) |
3608
+ | `handshake` | Widget finishes booting (once per mount) | `HandshakeResponse` (dashboard config) |
3609
+ | `localeChange` | User picks a different language | `string` (new BCP-47 tag) |
3610
+ | `messageFeedback` | User rates a reply 👍/👎 (or clears it) | `{ messageId: string; value: "up" \| "down" \| null }` |
3611
+ | `hostEvent` | Your page calls `chat.track(name, data)` | `{ name: string; data?: Record<string, scalar> }` |
3612
+ | `toolResult` | A [page tool](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/page-tools.md) call settles, or the visitor answers a question card | `{ toolCallId: string; name?: string; status?: "completed" \| "failed" \| "declined" \| "stopped" \| "interrupted"; durationMs?: number }` |
3538
3613
 
3539
3614
  ---
3540
3615
 
@@ -3976,21 +4051,220 @@ explicit `off()` is belt-and-suspenders. Either way works.
3976
4051
  | No events at all | `.on()` called before the instance was fully constructed. Use `init()`'s return value or a pre-boot hook |
3977
4052
  | Pre-boot hook never fires | Widget never mounted — check the public-key/deployment-id pair |
3978
4053
 
3979
- [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/troubleshooting.md) has the full diagnostic
4054
+ [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/troubleshooting.md) has the full diagnostic
3980
4055
  checklist.
3981
4056
 
3982
4057
  ---
3983
4058
 
3984
4059
  ## Next
3985
4060
 
3986
- - [Analytics integration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/analytics.md) — GA4, Mixpanel, Segment, Amplitude, PostHog, Sentry, multi-provider
3987
- - [Recipes](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md) — copy-paste scenarios
3988
- - [API reference § events](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/api-reference.md#events) — compact lookup
3989
- - [Configuration § callbacks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md#callbacks-shortcut-for-events)
4061
+ - [Analytics integration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/analytics.md) — GA4, Mixpanel, Segment, Amplitude, PostHog, Sentry, multi-provider
4062
+ - [Recipes](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md) — copy-paste scenarios
4063
+ - [API reference § events](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/api-reference.md#events) — compact lookup
4064
+ - [Configuration § callbacks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md#callbacks-shortcut-for-events)
4065
+
4066
+ ---
4067
+
4068
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/page-tools.md -->
4069
+
4070
+ # Page tools
4071
+
4072
+ Give the AI agent tools that act on your own page: open your booking form, read the visitor's cart, jump to a
4073
+ section, fill in a form. You describe each tool and write its function; the agent decides when to call it, the
4074
+ widget runs the function in the visitor's browser, and the agent continues the conversation with what it returned.
4075
+ Every page can offer different tools, so the agent can do on each page what that page is for.
4076
+
4077
+ A tool has the [WebMCP](https://webmachinelearning.github.io/webmcp/) shape (the W3C draft for tools a web page
4078
+ offers to AI agents), so a tool you write for the widget also works with a browser's own WebMCP support, and the
4079
+ other way round.
4080
+
4081
+ ```ts
4082
+ chat.registerTool({
4083
+ name: 'open_booking',
4084
+ description: 'Open the booking form on this page for a meeting type. Use it whenever the visitor wants to book a call.',
4085
+ inputSchema: {
4086
+ type: 'object',
4087
+ properties: { meetingType: { type: 'string', enum: ['sales', 'support'] } },
4088
+ required: ['meetingType'],
4089
+ },
4090
+ execute({ meetingType }) {
4091
+ bookingForm.open(meetingType);
4092
+ return { opened: true };
4093
+ },
4094
+ });
4095
+ ```
4096
+
4097
+ A visitor writes "I'd like to talk to sales"; the agent calls `open_booking` with `{ meetingType: 'sales' }`, your
4098
+ booking form opens, and the agent answers "The booking form is open, pick a time that suits you."
4099
+
4100
+ ## Adding tools
4101
+
4102
+ | Where you are | How |
4103
+ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------- |
4104
+ | Script tag | `HelpAI('registerTool', tool)`. Works before the widget has loaded: the loader queues it. |
4105
+ | npm | `chat.registerTool(tool, { signal })`, or `init({ tools: [...] })`. |
4106
+ | React | `useHelpAITool(tool)` in the component that owns the feature, or `<HelpAI tools={[...]} />`. |
4107
+ | `<web-ai-chat>` | `element.registerTool(tool)`, or the `tools` property (functions can't be attributes). |
4108
+ | Plain HTML | A form with `toolname` and `tooldescription` attributes ([Forms as tools](#forms-as-tools)); no script needed. |
4109
+ | A WebMCP browser | Tools registered with the browser's own `document.modelContext.registerTool()` are offered too ([WebMCP](#webmcp-browsers)). |
4110
+
4111
+ `registerTool` adds the tool for every widget on the page. Pass an `AbortSignal` to remove it again, for example when
4112
+ a single-page app leaves the route that owns it:
4113
+
4114
+ ```ts
4115
+ const route = new AbortController();
4116
+ chat.registerTool(addToCart, { signal: route.signal });
4117
+ // …when the visitor leaves the product page:
4118
+ route.abort();
4119
+ ```
4120
+
4121
+ `useHelpAITool` does this for you: the tool is registered while the component is mounted, `execute` always runs the
4122
+ latest render's function, and React's StrictMode double mount still leaves one registration.
4123
+
4124
+ ## A tool
4125
+
4126
+ | Field | What it is |
4127
+ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
4128
+ | `name` | Letters, digits, `_` and `-`, 58 characters at most; other characters become `_`. The agent sees `site__<name>`. A name registered again replaces the earlier tool. |
4129
+ | `description` | When the agent should use it and what it does, 1024 characters at most. The agent picks tools by their descriptions: say when, not only what. Without one, `title` (then `name`) is used. |
4130
+ | `title` | Optional. A short human name. |
4131
+ | `inputSchema` | Optional. [JSON Schema](https://json-schema.org/) of the input, an object. The agent fills it in; use `enum` and `required` to keep the input exact. Without one, the tool takes no input. |
4132
+ | `annotations.consequentialHint` | Optional. `true` for a tool with real consequences (an order, a booking, a message to someone): the visitor approves each call in the chat first, and the function runs only on Approve. |
4133
+ | `execute` | `(input, { signal }) => result`. Return a value or a promise of one; throw to report a failure. `signal` aborts when the visitor moves on before the call finishes. |
4134
+
4135
+ The `ModelContextTool` and `ToolAnnotations` types are exported for TypeScript; `ModelContextTool<{ sku: string }>`
4136
+ types `execute`'s input. WebMCP's other annotations (`readOnlyHint`, `untrustedContentHint`) are accepted and not used
4137
+ yet.
4138
+
4139
+ Nothing about a tool can break the chat: a tool without a `name` or an `execute` function is left out with a warning
4140
+ in the browser console, and every message still goes through.
4141
+
4142
+ ## Forms as tools
4143
+
4144
+ A form becomes a tool with two attributes, in every browser:
4145
+
4146
+ ```html
4147
+ <form toolname="request_demo" tooldescription="Request a product demo for the visitor." toolautosubmit>
4148
+ <label for="email">Work email</label>
4149
+ <input id="email" name="email" type="email" required />
4150
+ <input name="company" toolparamdescription="The visitor's company name" />
4151
+ <select name="plan">
4152
+ <option value="starter">Starter</option>
4153
+ <option value="pro">Pro</option>
4154
+ </select>
4155
+ <button>Request demo</button>
4156
+ </form>
4157
+ ```
4158
+
4159
+ - Each named field is an input the agent can fill: a `select` or radio group takes one of its values, a checkbox
4160
+ `true` or `false`, a number field a number, anything else text. Hidden, disabled and file fields are left out, and
4161
+ so are passwords: the visitor types those, never the chat.
4162
+ - A field's description is its `toolparamdescription`, else its label, else its `aria-description`; `required`
4163
+ fields are required.
4164
+ - The agent fills the fields the way a visitor would (your framework's change handlers run). With `toolautosubmit`
4165
+ the form is then submitted; without it the visitor checks the form and presses its button. When a field still
4166
+ blocks the submit (a password, or a value the browser rejects), the form isn't submitted and the agent is told which
4167
+ field needs the visitor.
4168
+
4169
+ ## WebMCP browsers
4170
+
4171
+ In a browser with WebMCP (`document.modelContext`: in Chrome, turn on `chrome://flags/#enable-experimental-web-platform-features`
4172
+ or join the origin trial), the tools the page registered with the browser are offered to the agent too, and the widget
4173
+ runs them through the browser. A `<form toolname>` is the exception: such a browser lists it too, but the widget fills
4174
+ it itself, as in every other browser, so your form's own submit handler keeps working and passwords stay the
4175
+ visitor's. Elsewhere, nothing changes.
4176
+
4177
+ ## Which tools a message offers
4178
+
4179
+ The widget reads the page's tools when the visitor sends each message: the browser's WebMCP tools, then forms, then
4180
+ the `tools` option, then `registerTool`. For a name in more than one place, the later one wins. When the agent calls a
4181
+ tool, the widget reads them again and runs the current function of that name, so a single-page app's route change
4182
+ applies straight away, with nothing to keep in sync. A call to a tool the page no longer has tells the agent the page
4183
+ doesn't offer it right now. So does a call to a tool the message didn't offer at all (the agent repeating an earlier
4184
+ call after a route change): the server answers it with "This page doesn't offer that action right now.", tells the agent
4185
+ not to call it again this turn, and the agent carries on from what it knows or asks the visitor.
4186
+
4187
+ ## What the agent gets back
4188
+
4189
+ - **A return value** becomes the tool's result, as JSON: dates become strings, `undefined` becomes `null`, functions
4190
+ are dropped, a page element is named (`"[dialog]"`), a repeated object reads `"[circular]"`, and a result over
4191
+ 30,000 characters is sent as `{ truncated: true, preview }`. Return what the agent needs to answer well, such as
4192
+ `{ opened: true }` or `{ items: 2, total: '$48' }`.
4193
+ - **A thrown error** (or a rejected promise) reaches the agent as the tool's error, with its message, so it can tell
4194
+ the visitor or try another way. For an expected miss ("that product is out of stock") a normal result such as
4195
+ `{ ok: false, reason: 'out of stock' }` gives the agent more to work with.
4196
+
4197
+ With several calls in one step, the agent waits for all of them, and for any approvals, then continues once.
4198
+
4199
+ ## Each call runs once
4200
+
4201
+ - **Tabs.** Only the tab where the visitor sent the message runs the calls in its reply; another tab of the same
4202
+ conversation shows them running, then the agent's answer.
4203
+ - **Reloads and navigation.** A call that hadn't started when the page reloaded runs once after the reload. A call
4204
+ that was running is never run again: the agent is told the page reloaded, so it may or may not have taken effect,
4205
+ and checks with the visitor; its card reads "Not completed". A result that was ready but not yet sent is sent after the reload. The widget keeps
4206
+ this note per tab in `sessionStorage`, so it also covers a navigation to another page of your site.
4207
+ - **Leaving the page.** Results go out with `keepalive`, so they arrive even when the page navigates straight after.
4208
+ A tool that navigates should return first and leave after:
4209
+
4210
+ ```ts
4211
+ execute({ path }) {
4212
+ setTimeout(() => location.assign(path), 0); // navigate after the result is sent
4213
+ return { navigating: path };
4214
+ },
4215
+ ```
4216
+
4217
+ - **The script loaded twice, or two widgets.** The call still runs once.
4218
+ - **No time limit.** The agent waits for the result. While a tool runs, the chat shows Stop. If the visitor presses it,
4219
+ or sends another message first, the call's `signal` aborts, its result is never sent, and its card reads
4220
+ "Not completed". A stopped call never runs again, not even after a reload.
4221
+
4222
+ When `sessionStorage` is blocked (some private modes), the note lives in memory, so a reload can't tell a call that
4223
+ ran from one that didn't; everything else works the same.
4224
+
4225
+ ## What the visitor sees
4226
+
4227
+ A tool that runs on its own appears in the transcript only when the deployment shows tool calls
4228
+ (`behavior.showToolCalls`), with its input and result: "Running", then "Completed" or "Error" (the tool failed), or
4229
+ "Not completed" when the visitor stopped it or moved on, or a reload cut it short. A tool with `consequentialHint` always shows an approval card with the input; Reject tells
4230
+ the agent the visitor declined, and the function never runs.
4231
+
4232
+ ## Events
4233
+
4234
+ Each call this page settles fires `toolResult` with `{ toolCallId, name, status, durationMs }`: `status` is
4235
+ `completed`, `failed`, `declined` (the visitor rejected it), `stopped` (the visitor pressed Stop) or `interrupted` (a
4236
+ reload cut it short). It never carries the input or the result.
4237
+
4238
+ ```ts
4239
+ chat.on('toolResult', ({ name, status, durationMs }) => analytics.track('help_ai_tool', { name, status, durationMs }));
4240
+ ```
4241
+
4242
+ ## Security
4243
+
4244
+ - Tools run with your page's full privileges, as code you wrote. Anyone can also call your functions from the
4245
+ browser's developer tools, so a tool may do only what the visitor could do on the page themselves.
4246
+ - The agent chooses the input. Check it in `execute` as you would a form submission, and mark tools with real
4247
+ consequences (payments, deletions, messages to other people) `consequentialHint: true`, or confirm in your own UI.
4248
+ - The definitions are sent with each message and the results are stored in the conversation, like any tool's result,
4249
+ so never put secrets in a description or a result.
4250
+
4251
+ ## Testing
4252
+
4253
+ `testing/page-tools-manual.md` walks through every case above in a real browser
4254
+ on the `dev/page-tools.html` playground, with a real model or the mock backend.
4255
+
4256
+ ## Troubleshooting
4257
+
4258
+ - **The agent never uses the tool:** write the description as an instruction ("Use it whenever the visitor wants to
4259
+ book a call"), and check the console for a "skipped a tool" warning.
4260
+ - **The chat waits after a tool:** the function never settled (a promise that doesn't resolve). Return, or throw.
4261
+ - **"This page doesn't offer … right now":** the call came after the tool was removed (a route change aborted its
4262
+ signal), or the agent tried a tool this page doesn't register. Keep a tool registered while the agent may still use
4263
+ it.
3990
4264
 
3991
4265
  ---
3992
4266
 
3993
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md -->
4267
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md -->
3994
4268
 
3995
4269
  # Theming & customization
3996
4270
 
@@ -4317,7 +4591,7 @@ init({
4317
4591
 
4318
4592
  ## Header actions
4319
4593
 
4320
- See [Configuration § Header actions](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md#header-actions)
4594
+ See [Configuration § Header actions](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md#header-actions)
4321
4595
  for the full semantics. Quick customization examples:
4322
4596
 
4323
4597
  ### Minimal chrome
@@ -4524,7 +4798,7 @@ are for what tokens don't cover (shadows, corners, borders).
4524
4798
 
4525
4799
  For truly bespoke designs (e.g., replacing the launcher with your
4526
4800
  own component), use `launcher.hidden: true` + custom trigger, or a
4527
- [no-script trigger](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/api-reference.md#no-script-triggers).
4801
+ [no-script trigger](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/api-reference.md#no-script-triggers).
4528
4802
 
4529
4803
  ---
4530
4804
 
@@ -4556,16 +4830,16 @@ can always override.
4556
4830
 
4557
4831
  ## Next
4558
4832
 
4559
- - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md) — listening to chat
4833
+ - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md) — listening to chat
4560
4834
  interactions, integrating with analytics.
4561
- - [Recipes](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md) — copy-paste examples for common
4835
+ - [Recipes](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md) — copy-paste examples for common
4562
4836
  customization scenarios.
4563
- - [Configuration reference](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md) — the full option
4837
+ - [Configuration reference](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md) — the full option
4564
4838
  table.
4565
4839
 
4566
4840
  ---
4567
4841
 
4568
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md -->
4842
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md -->
4569
4843
 
4570
4844
  # Recipes
4571
4845
 
@@ -5289,13 +5563,13 @@ brand accent set in the dashboard.
5289
5563
 
5290
5564
  ## Next
5291
5565
 
5292
- - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md) — full event API
5293
- - [Configuration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md) — every option
5294
- - [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/troubleshooting.md) — when things go wrong
5566
+ - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md) — full event API
5567
+ - [Configuration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md) — every option
5568
+ - [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/troubleshooting.md) — when things go wrong
5295
5569
 
5296
5570
  ---
5297
5571
 
5298
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/analytics.md -->
5572
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/analytics.md -->
5299
5573
 
5300
5574
  # Analytics integration
5301
5575
 
@@ -5327,8 +5601,13 @@ internal event bus, and you subscribe as many listeners as you want.
5327
5601
  <!-- 2. Load the widget -->
5328
5602
  <script src="https://cdn.help.ai/sdk/js/elements/latest/elements.js" data-public-key="agent_pk_..." data-ai-agent-deployment-id="01900000-0000-7000-8000-000000000000" defer></script>
5329
5603
 
5330
- <!-- 3. Subscribe to every widget event with one wildcard hook -->
5604
+ <!-- 3. Subscribe to every widget event with one wildcard hook. The stub queues the call until the deferred script runs. -->
5331
5605
  <script>
5606
+ window.HelpAI =
5607
+ window.HelpAI ||
5608
+ function () {
5609
+ (HelpAI.q = HelpAI.q || []).push(arguments);
5610
+ };
5332
5611
  HelpAI('hook', 'default', '*', (chat, event, payload) => {
5333
5612
  gtag('event', `chat_${event}`, flatten(payload));
5334
5613
  });
@@ -5351,7 +5630,7 @@ event.
5351
5630
 
5352
5631
  Every interactive action emits one event with a typed payload. Subscribe
5353
5632
  via `chat.on(name, fn)` (instance) or `HelpAI.hook(widgetId, name, fn)`
5354
- (global, pre-boot-safe). Full schema in [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md).
5633
+ (global, pre-boot-safe). Full schema in [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md).
5355
5634
 
5356
5635
  | Category | Event | Payload |
5357
5636
  | ---------------- | --------------------- | -------------------------------------------------- |
@@ -5377,6 +5656,7 @@ via `chat.on(name, fn)` (instance) or `HelpAI.hook(widgetId, name, fn)`
5377
5656
  | | `soundToggle` | `{ muted }` |
5378
5657
  | | `sidebarToggle` | `{ collapsed }` (page mode) |
5379
5658
  | | `calloutDismiss` | `void` |
5659
+ | **Your page** | `hostEvent` | `{ name, data? }` (from `chat.track()`) |
5380
5660
  | **Lifecycle** | `error` | `unknown` (any unhandled error) |
5381
5661
  | | `handshake` | `HandshakeResponse` (full handshake payload) |
5382
5662
  | | `conversationRebound` | `{ previous, current }` |
@@ -5691,6 +5971,32 @@ chat.on('close', () => {
5691
5971
 
5692
5972
  ## Common patterns
5693
5973
 
5974
+ ### Your own events (`chat.track`)
5975
+
5976
+ Report what the visitor does on your site, outside the chat, with `chat.track(name, data)`:
5977
+
5978
+ ```ts
5979
+ chat.track('plan_viewed', { plan: 'pro' });
5980
+ chat.track('cart_updated', { items: 2, total: 48.5 });
5981
+ ```
5982
+
5983
+ Each call does two things:
5984
+
5985
+ - **Analytics.** It sends one hit to help.ai's Elements analytics as a `hostEvent`, with your event name and data,
5986
+ like the widget's own events. A deployment with tracking off (or a browser sending Global Privacy Control or Do
5987
+ Not Track) sends nothing.
5988
+ - **The agent.** The widget keeps your last 10 events and sends them with the visitor's next message, as
5989
+ `recentEvents` in the page context (`{ name, data?, secondsAgo }`, oldest first), so an answer can take into
5990
+ account what the visitor just did: "I see you were looking at the Pro plan." Like the rest of the page context, the
5991
+ agent treats them as information from your site, never as instructions. They live only in this page view.
5992
+
5993
+ The name is 1–64 characters. The data is flat: strings, numbers and booleans (other values are left out), up to 256
5994
+ characters as JSON (longer data is not sent; the name still is). Nothing personal should go in either: use ids and
5995
+ plan names, not emails. `track()` also fires the `hostEvent` event, so your own listeners see it.
5996
+
5997
+ Also `HelpAI('track', name, data)` with the script tag, `element.track(name, data)` on `<web-ai-chat>`, and
5998
+ `useHelpAI().track` in React.
5999
+
5694
6000
  ### Identify the visitor
5695
6001
 
5696
6002
  The widget mints a stable anonymous `visitorId` on first load and
@@ -5844,14 +6150,14 @@ yourself — see the snippets above.
5844
6150
 
5845
6151
  ## See also
5846
6152
 
5847
- - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md) — full event reference, payload shapes, pre-boot queue semantics
5848
- - [API reference](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/api-reference.md) — `ChatWidgetInstance` shape
5849
- - [Recipes](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md) — other end-to-end snippets
5850
- - [Security & privacy](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md) — what data flows where
6153
+ - [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md) — full event reference, payload shapes, pre-boot queue semantics
6154
+ - [API reference](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/api-reference.md) — `ChatWidgetInstance` shape
6155
+ - [Recipes](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md) — other end-to-end snippets
6156
+ - [Security & privacy](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md) — what data flows where
5851
6157
 
5852
6158
  ---
5853
6159
 
5854
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md -->
6160
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md -->
5855
6161
 
5856
6162
  # Security & privacy
5857
6163
 
@@ -6043,7 +6349,7 @@ unsent text values in addition to identity and UI state, so adapter code owns
6043
6349
  their storage destination, retention, and privacy behavior. Use cases include
6044
6350
  encrypted `localStorage`, `sessionStorage`, and in-memory consent fallbacks.
6045
6351
 
6046
- [Recipes § Custom storage](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#custom-storage-adapter).
6352
+ [Recipes § Custom storage](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#custom-storage-adapter).
6047
6353
 
6048
6354
  ---
6049
6355
 
@@ -6342,10 +6648,13 @@ and anyone can base64url-decode it. Never put a secret in context.
6342
6648
 
6343
6649
  ### Key rotation
6344
6650
 
6345
- - **public keys** — rotate from the dashboard. Old keys are deactivated
6346
- instantly; update your embeds.
6347
- - **secret key** — user tokens signed with a replaced secret key stop verifying, so every verified user is signed out
6348
- until your server signs new ones with the new key.
6651
+ The dashboard has no key rotation today.
6652
+
6653
+ - **public key** — public by design: it only names the deployment. Limit where it works with the deployment's
6654
+ **Allowed websites**.
6655
+ - **secret key** — keep it on your server. If it leaks, create a new deployment (it gets new keys), move your embed
6656
+ and your token signing to it, and delete the old one. User tokens signed with the old key stop verifying, so every
6657
+ verified user is signed out until your server signs new ones.
6349
6658
 
6350
6659
  ---
6351
6660
 
@@ -6492,7 +6801,7 @@ We respond within 24 hours and coordinate disclosure on your schedule.
6492
6801
 
6493
6802
  ---
6494
6803
 
6495
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/browser-support.md -->
6804
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/browser-support.md -->
6496
6805
 
6497
6806
  # Browser support
6498
6807
 
@@ -6799,7 +7108,7 @@ with:
6799
7108
 
6800
7109
  ---
6801
7110
 
6802
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/troubleshooting.md -->
7111
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/troubleshooting.md -->
6803
7112
 
6804
7113
  # Troubleshooting
6805
7114
 
@@ -6895,7 +7204,7 @@ for (const k of Object.keys(localStorage)) {
6895
7204
  3. **Any CSP errors in the console?** — `"Refused to connect to
6896
7205
  https://help.ai/api/agent because it violates the following Content
6897
7206
  Security Policy…"` means you need to add `help.ai` to your
6898
- `connect-src`. See [Security § CSP](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#content-security-policy).
7207
+ `connect-src`. See [Security § CSP](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#content-security-policy).
6899
7208
 
6900
7209
  ---
6901
7210
 
@@ -6978,7 +7287,7 @@ first.
6978
7287
  ### Symptom: widget ignores my CSS
6979
7288
 
6980
7289
  That's by design. The widget lives inside a shadow root — your page
6981
- CSS can't reach inside. Use the [theming options](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md)
7290
+ CSS can't reach inside. Use the [theming options](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md)
6982
7291
  instead.
6983
7292
 
6984
7293
  For advanced customization, override CSS custom properties on the
@@ -7243,7 +7552,7 @@ font-src 'self' https:;
7243
7552
  media-src 'self' blob:; # For voice recording
7244
7553
  ```
7245
7554
 
7246
- Full CSP guide: [Security § CSP](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#content-security-policy).
7555
+ Full CSP guide: [Security § CSP](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#content-security-policy).
7247
7556
 
7248
7557
  ---
7249
7558
 
@@ -7308,7 +7617,7 @@ provide `i18n.availableLocales` and include `language` in `header.actions`.
7308
7617
 
7309
7618
  ## Getting more help
7310
7619
 
7311
- 1. **Read the [FAQ](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/faq.md)** — most common questions answered
7620
+ 1. **Read the [FAQ](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/faq.md)** — most common questions answered
7312
7621
  there.
7313
7622
 
7314
7623
  2. **Check our GitHub issues**: [github.com/help-ai/elements](https://github.com/help-ai/elements/issues).
@@ -7327,7 +7636,7 @@ provide `i18n.availableLocales` and include `language` in `header.actions`.
7327
7636
 
7328
7637
  ---
7329
7638
 
7330
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/faq.md -->
7639
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/faq.md -->
7331
7640
 
7332
7641
  # FAQ
7333
7642
 
@@ -7367,7 +7676,7 @@ own builds. Your public key gates the backend, not the frontend.
7367
7676
  ### What browsers are supported?
7368
7677
 
7369
7678
  Chrome/Edge 100+, Safari 15+, Firefox 100+, iOS Safari 15+. No IE11.
7370
- See [Browser support](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/browser-support.md).
7679
+ See [Browser support](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/browser-support.md).
7371
7680
 
7372
7681
  ---
7373
7682
 
@@ -7386,11 +7695,11 @@ yourself) and serve it from your CDN. Point your `<script src>` at your hosted
7386
7695
  URL. Self-hosting is also what unlocks **chunked delivery** (only changed code
7387
7696
  re-downloads across releases) behind a single stable URL the customer never has
7388
7697
  to change — see
7389
- [Caching, versioning & self-hosting](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/installation.md#caching-versioning--self-hosting).
7698
+ [Caching, versioning & self-hosting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md#caching-versioning--self-hosting).
7390
7699
 
7391
7700
  ### Can I use this with a tag manager (GTM)?
7392
7701
 
7393
- Yes. Use the async loader snippet ([Path B](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/installation.md#path-b--async-loader-snippet))
7702
+ Yes. Use the async loader snippet ([Path B](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md#path-b--async-loader-snippet))
7394
7703
  inside a Custom HTML tag. All `HelpAI(...)` calls queue until the
7395
7704
  bundle lands.
7396
7705
 
@@ -7398,7 +7707,7 @@ bundle lands.
7398
7707
 
7399
7708
  Yes — and there's an optional `presentation.iframe: true` flag that wraps the
7400
7709
  widget in its OWN iframe for extra isolation. See
7401
- [Configuration § presentation.iframe](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md#presentationiframe).
7710
+ [Configuration § presentation.iframe](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md#presentationiframe).
7402
7711
 
7403
7712
  ### Does it work in shadow DOM?
7404
7713
 
@@ -7408,15 +7717,15 @@ custom element on your page). Everything just works.
7408
7717
 
7409
7718
  ### Does it work with React / Next.js?
7410
7719
 
7411
- Yes. Full walkthrough: [Framework integrations § Next.js](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md#nextjs).
7720
+ Yes. Full walkthrough: [Framework integrations § Next.js](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md#nextjs).
7412
7721
 
7413
7722
  ### Does it work with Vue / Svelte / SolidJS / Angular?
7414
7723
 
7415
- Yes. See [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md).
7724
+ Yes. See [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md).
7416
7725
 
7417
7726
  ### Does it work with WordPress / Shopify / Webflow / Squarespace?
7418
7727
 
7419
- Yes. [Framework integrations § CMS](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md#wordpress).
7728
+ Yes. [Framework integrations § CMS](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md#wordpress).
7420
7729
 
7421
7730
  ---
7422
7731
 
@@ -7425,12 +7734,12 @@ Yes. [Framework integrations § CMS](https://cdn.help.ai/sdk/js/elements/1.10.0/
7425
7734
  ### Can I change the launcher icon?
7426
7735
 
7427
7736
  Yes. Pick from presets (`chat`, `spark`, `message`, `help`, `wand`)
7428
- or pass raw SVG. See [Theming § Icons](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md#icons).
7737
+ or pass raw SVG. See [Theming § Icons](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md#icons).
7429
7738
 
7430
7739
  ### Can I match my brand colors?
7431
7740
 
7432
7741
  Yes. Set `theme.accent`, `theme.accentText`, `theme.radius`,
7433
- `theme.fontFamily`. See [Theming § Colors](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md#color-overrides).
7742
+ `theme.fontFamily`. See [Theming § Colors](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md#color-overrides).
7434
7743
 
7435
7744
  ### Can I change the font?
7436
7745
 
@@ -7440,7 +7749,7 @@ respects any CSS font stack you provide.
7440
7749
  ### Can I hide the launcher and open the widget from my own button?
7441
7750
 
7442
7751
  Yes. Set `launcher: { hidden: true }`, then call `chat.open()` from
7443
- your button's click handler. [Recipes § Custom launcher](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#custom-launcher-button).
7752
+ your button's click handler. [Recipes § Custom launcher](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#custom-launcher-button).
7444
7753
 
7445
7754
  ### Can I change the welcome message?
7446
7755
 
@@ -7449,24 +7758,24 @@ widget just renders what the backend sends.
7449
7758
 
7450
7759
  ### Can I override UI strings?
7451
7760
 
7452
- Yes, per-locale or flat. See [Theming § Strings](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md#strings-overrides).
7761
+ Yes, per-locale or flat. See [Theming § Strings](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md#strings-overrides).
7453
7762
 
7454
7763
  ### Can I have multiple widgets on one page?
7455
7764
 
7456
7765
  Yes — with distinct `widgetId` values. Each gets its own chat
7457
- thread, storage, and events. [Recipes § Multi-widget](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#multiple-widgets-on-one-page).
7766
+ thread, storage, and events. [Recipes § Multi-widget](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#multiple-widgets-on-one-page).
7458
7767
 
7459
7768
  ### Can I show the widget only on certain pages?
7460
7769
 
7461
7770
  Yes — just skip the `init()` call on pages where you don't want it.
7462
7771
  Or conditionally mount/unmount based on the URL.
7463
- [Recipes § Conditional show](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#conditionally-show-based-on-url).
7772
+ [Recipes § Conditional show](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#conditionally-show-based-on-url).
7464
7773
 
7465
7774
  ### Can I use it in a specific language?
7466
7775
 
7467
7776
  Yes. Force via `i18n.locale: 'fr-CA'`. Let users switch via
7468
7777
  `i18n.availableLocales: ['en', 'fr', 'es']`. Full details: [Theming §
7469
- Internationalization](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md#internationalization).
7778
+ Internationalization](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md#internationalization).
7470
7779
 
7471
7780
  ### Can I change the widget's position on mobile?
7472
7781
 
@@ -7503,7 +7812,7 @@ allowlisted event metadata through 1×1 pixel requests; it never sends message
7503
7812
  text or form values and can be disabled with `tracking.enabled: false`. GPC and
7504
7813
  DNT disable it automatically. No cookies or fingerprinting.
7505
7814
 
7506
- Full breakdown: [Security & privacy § data collected](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md#what-data-the-widget-collects).
7815
+ Full breakdown: [Security & privacy § data collected](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md#what-data-the-widget-collects).
7507
7816
 
7508
7817
  ### Does the widget use cookies?
7509
7818
 
@@ -7523,7 +7832,7 @@ Help AI API + your deployment's configured model provider.
7523
7832
  It stores data about identified users (when you pass `user.id`) or
7524
7833
  anonymous visitors. Your DPA (Data Processing Agreement) with Help
7525
7834
  AI covers the processing terms. For consent management, see
7526
- [Recipes § Gate behind consent](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#gate-the-widget-behind-consent).
7835
+ [Recipes § Gate behind consent](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#gate-the-widget-behind-consent).
7527
7836
 
7528
7837
  ### Can visitors delete their chat history?
7529
7838
 
@@ -7538,7 +7847,7 @@ Yes — pass a custom in-memory storage adapter. Adapter-managed identity,
7538
7847
  conversation, draft, preference, and UI state then evaporates on reload. The
7539
7848
  optional logger debug level is separate: calling `setDebug` persists
7540
7849
  `helpai.debug` directly in `localStorage` until the host clears it.
7541
- [Recipes § Custom storage adapter](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#custom-storage-adapter).
7850
+ [Recipes § Custom storage adapter](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#custom-storage-adapter).
7542
7851
 
7543
7852
  ### Does the widget track visitors across sites?
7544
7853
 
@@ -7563,7 +7872,7 @@ init({
7563
7872
  not an auth credential. Browser public access uses the matching
7564
7873
  `publicKey` + `aiAgentDeploymentId` pair, or the deployment ID alone for
7565
7874
  intentional guest mode.
7566
- See [Recipes § Logged-in user personalization](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#logged-in-user-personalization).
7875
+ See [Recipes § Logged-in user personalization](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#logged-in-user-personalization).
7567
7876
 
7568
7877
  ### How do I integrate with my analytics (GA / Segment / Mixpanel)?
7569
7878
 
@@ -7582,7 +7891,7 @@ One-line pre-boot hook forwards every event:
7582
7891
  </script>
7583
7892
  ```
7584
7893
 
7585
- Full examples: [Recipes § Analytics forwarding](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md#analytics-forwarding).
7894
+ Full examples: [Recipes § Analytics forwarding](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md#analytics-forwarding).
7586
7895
 
7587
7896
  ### How do I capture errors in Sentry / Datadog?
7588
7897
 
@@ -7767,7 +8076,7 @@ table.
7767
8076
 
7768
8077
  ---
7769
8078
 
7770
- <!-- https://cdn.help.ai/sdk/js/elements/1.10.0/docs/README.md -->
8079
+ <!-- https://cdn.help.ai/sdk/js/elements/1.12.0/docs/README.md -->
7771
8080
 
7772
8081
  # Help AI Elements — SDK Documentation
7773
8082
 
@@ -7796,7 +8105,7 @@ it → the panel opens → they can chat.
7796
8105
  Get the public key and deployment ID from [help.ai](https://help.ai) →
7797
8106
  **Dashboard → Deployments**.
7798
8107
 
7799
- [**Continue with the quickstart →**](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/quickstart.md)
8108
+ [**Continue with the quickstart →**](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/quickstart.md)
7800
8109
 
7801
8110
  ---
7802
8111
 
@@ -7804,19 +8113,20 @@ Get the public key and deployment ID from [help.ai](https://help.ai) →
7804
8113
 
7805
8114
  | You want to… | Read |
7806
8115
  | ----------------------------------------------------------- | --------------------------------------------- |
7807
- | Install the widget end-to-end | [**Quickstart**](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/quickstart.md) |
7808
- | See every install method (NPM, Web Component, React) | [Installation](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/installation.md) |
7809
- | Customize every option | [Configuration reference](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md) |
7810
- | Match my brand colors and typography | [Theming & customization](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md) |
7811
- | Send chat events to my analytics | [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/events-and-hooks.md) |
7812
- | Wire GA4 / Mixpanel / Segment / multi-provider | [Analytics integration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/analytics.md) |
7813
- | Integrate with Next.js / Vue / Svelte / WordPress / Shopify | [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/frameworks.md) |
7814
- | Copy a working example | [Recipes](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/recipes.md) |
7815
- | Diagnose "why isn't this working" | [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/troubleshooting.md) |
7816
- | Quick answer to a common question | [FAQ](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/faq.md) |
7817
- | Compact API reference for lookup | [API reference](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/api-reference.md) |
7818
- | Understand what data the widget sees | [Security & privacy](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/security-privacy.md) |
7819
- | Check browser compatibility | [Browser support](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/browser-support.md) |
8116
+ | Install the widget end-to-end | [**Quickstart**](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/quickstart.md) |
8117
+ | See every install method (NPM, Web Component, React) | [Installation](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md) |
8118
+ | Customize every option | [Configuration reference](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md) |
8119
+ | Match my brand colors and typography | [Theming & customization](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md) |
8120
+ | Send chat events to my analytics | [Events & hooks](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/events-and-hooks.md) |
8121
+ | Wire GA4 / Mixpanel / Segment / multi-provider | [Analytics integration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/analytics.md) |
8122
+ | Integrate with Next.js / Vue / Svelte / WordPress / Shopify | [Framework integrations](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/frameworks.md) |
8123
+ | Copy a working example | [Recipes](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/recipes.md) |
8124
+ | Let the AI agent act on my page | [Page tools](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/page-tools.md) |
8125
+ | Diagnose "why isn't this working" | [Troubleshooting](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/troubleshooting.md) |
8126
+ | Quick answer to a common question | [FAQ](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/faq.md) |
8127
+ | Compact API reference for lookup | [API reference](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/api-reference.md) |
8128
+ | Understand what data the widget sees | [Security & privacy](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/security-privacy.md) |
8129
+ | Check browser compatibility | [Browser support](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/browser-support.md) |
7820
8130
 
7821
8131
  ---
7822
8132
 
@@ -7878,7 +8188,7 @@ Five ways to install. Pick whichever fits your site:
7878
8188
  | **ESM via CDN** | Plain HTML, sandboxes, MDX — no build, no NPM install | `import { mount } from 'https://cdn.jsdelivr.net/npm/@helpai/elements@<version>/elements.esm.js'` |
7879
8189
 
7880
8190
  All five use the same underlying library. Same options, same events,
7881
- same behavior. Full comparison: [Installation](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/installation.md).
8191
+ same behavior. Full comparison: [Installation](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/installation.md).
7882
8192
 
7883
8193
  ---
7884
8194
 
@@ -7933,14 +8243,14 @@ fuller example showing the most common options in one place:
7933
8243
  </script>
7934
8244
  ```
7935
8245
 
7936
- Every option explained in [Configuration](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/configuration.md). Every
7937
- customization path in [Theming](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/theming.md).
8246
+ Every option explained in [Configuration](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/configuration.md). Every
8247
+ customization path in [Theming](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/theming.md).
7938
8248
 
7939
8249
  ---
7940
8250
 
7941
8251
  ## Support
7942
8252
 
7943
- - **Questions?** [FAQ](https://cdn.help.ai/sdk/js/elements/1.10.0/docs/faq.md) — common answers first. [support@help.ai](mailto:support@help.ai) for anything else.
8253
+ - **Questions?** [FAQ](https://cdn.help.ai/sdk/js/elements/1.12.0/docs/faq.md) — common answers first. [support@help.ai](mailto:support@help.ai) for anything else.
7944
8254
  - **Found a bug?** File an issue at [github.com/help-ai/elements](https://github.com/help-ai/elements/issues).
7945
8255
  - **Need a feature?** Same place — we read every request.
7946
8256
  - **Status page:** [help.ai/status](https://help.ai/status).