@helpai/elements 0.36.1 → 0.37.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/index.d.ts CHANGED
@@ -70,9 +70,10 @@ type StringsOverride = LocaleStrings | Partial<Record<string, LocaleStrings>>;
70
70
  *
71
71
  * Storage holds three things, each under its own key:
72
72
  *
73
- * 1. **`visitorId`** — anonymous browser-level identifier, minted once per
74
- * widget instance and reused forever. Sent on every backend request so
75
- * the server can attach per-visitor settings, history, etc.
73
+ * 1. **`visitorId`** — anonymous browser-level identifier, minted once and
74
+ * reused forever. **Brand-global** (NOT scoped to widget/deployment): one
75
+ * anonymous "who is this browser" id, shared across every widget + deployment
76
+ * of this brand. Sent on every backend request.
76
77
  * 2. **`conversationId`** — the active conversation thread. The backend is the
77
78
  * source of truth for messages; we store only the id and re-fetch on
78
79
  * reload via `transport.loadConversation()`.
@@ -80,8 +81,13 @@ type StringsOverride = LocaleStrings | Partial<Record<string, LocaleStrings>>;
80
81
  * sound mute). Cached locally for instant render-before-network, then
81
82
  * reconciled with the server's copy on each `connect()`.
82
83
  *
83
- * Keys are namespaced as `${brand.cssPrefix}.${widgetId}.${field}` so two
84
- * widgets on the same brand keep their state cleanly separated.
84
+ * Everything EXCEPT `visitorId` is namespaced as
85
+ * `${brand.cssPrefix}.${widgetId}.${deploymentId}.${field}` (the deployment id
86
+ * is dropped when absent) so two widgets — or two AI agent deployments — keep
87
+ * their state cleanly separated; pointing a widget at a different
88
+ * `aiAgentDeploymentId` starts from fresh conversation / prefs / panel state.
89
+ * `visitorId` is the deliberate exception: it stays global so the same browser
90
+ * is one anonymous visitor everywhere (`${brand.cssPrefix}.visitorId`).
85
91
  *
86
92
  * Storage is pluggable via {@link ClientStorage} — pass a custom adapter
87
93
  * to add encryption, logging, or use a non-localStorage backend.
package/index.mjs CHANGED
@@ -1025,9 +1025,10 @@ function fillRandom(view) {
1025
1025
 
1026
1026
  // src/core/persistence.ts
1027
1027
  var log2 = logger.scope("persistence");
1028
- function createPersistence(widgetId, storage = defaultStorage) {
1029
- const prefix = `${BRAND.cssPrefix}.${widgetId}`;
1030
- const KEY_VISITOR = `${prefix}.visitorId`;
1028
+ function createPersistence(widgetId, storage = defaultStorage, deploymentId) {
1029
+ const scope = deploymentId ? `${widgetId}.${deploymentId}` : widgetId;
1030
+ const prefix = `${BRAND.cssPrefix}.${scope}`;
1031
+ const KEY_VISITOR = `${BRAND.cssPrefix}.visitorId`;
1031
1032
  const KEY_CONVERSATION = `${prefix}.conversationId`;
1032
1033
  const KEY_USER_PREFS = `${prefix}.userPrefs`;
1033
1034
  const KEY_PANEL_OPEN = `${prefix}.panelOpen`;
@@ -1045,14 +1046,14 @@ function createPersistence(widgetId, storage = defaultStorage) {
1045
1046
  return minted;
1046
1047
  },
1047
1048
  setVisitorId(id) {
1048
- log2.debug("setVisitorId (rebind)", { id, widgetId });
1049
+ log2.debug("setVisitorId (rebind)", { id, scope });
1049
1050
  storage.set(KEY_VISITOR, id);
1050
1051
  },
1051
1052
  loadConversationId() {
1052
1053
  return storage.get(KEY_CONVERSATION) ?? void 0;
1053
1054
  },
1054
1055
  saveConversationId(id) {
1055
- log2.trace("saveConversationId", { id, widgetId });
1056
+ log2.trace("saveConversationId", { id, scope });
1056
1057
  if (id) storage.set(KEY_CONVERSATION, id);
1057
1058
  else storage.remove(KEY_CONVERSATION);
1058
1059
  },
@@ -4163,7 +4164,7 @@ function themeIcon(mode) {
4163
4164
  return /* @__PURE__ */ jsx9(ThemeAutoIcon, {});
4164
4165
  }
4165
4166
  function localeCode(locale) {
4166
- return (locale.split("-")[0] || locale).toUpperCase();
4167
+ return (locale.split("-")[0] ?? locale).toUpperCase();
4167
4168
  }
4168
4169
  function HeaderActions({ panelProps, variant }) {
4169
4170
  const { options, panelSize, feedback, onClose, onClear, onExpand, onFullscreen, onPopOut, onSoundToggle } = panelProps;
@@ -6715,7 +6716,9 @@ import { jsx as jsx36, jsxs as jsxs31 } from "preact/jsx-runtime";
6715
6716
  var log17 = logger.scope("app");
6716
6717
  var p32 = BRAND.cssPrefix;
6717
6718
  function App({ options, hostElement, bus }) {
6718
- const [persistence] = useState13(() => createPersistence(options.widgetId, options.storage));
6719
+ const [persistence] = useState13(
6720
+ () => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
6721
+ );
6719
6722
  const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
6720
6723
  const initialSettings = persistence.loadUserPrefs();
6721
6724
  const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
@@ -7903,7 +7906,7 @@ function createWidgetRuntime(params) {
7903
7906
  function resolveInitialHostMode(options) {
7904
7907
  if (options.mode === "standalone") return "standalone";
7905
7908
  if (options.mode === "inline") return "inline";
7906
- const persistence = createPersistence(options.widgetId, options.storage);
7909
+ const persistence = createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId);
7907
7910
  const { panelOpen, panelSize } = resolveInitialPanelState(
7908
7911
  options,
7909
7912
  currentViewportWidth(),
@@ -8018,7 +8021,7 @@ function mount(opts) {
8018
8021
  });
8019
8022
  mountResult.hostElement.dataset.widgetId = widgetId;
8020
8023
  const bus = new EventBus();
8021
- const persistence = createPersistence(widgetId, resolved.storage);
8024
+ const persistence = createPersistence(widgetId, resolved.storage, resolved.aiAgentDeploymentId);
8022
8025
  const reportError = (error) => {
8023
8026
  bus.emit("error", error);
8024
8027
  runtime.getOptions().onError?.(error);
package/package.json CHANGED
@@ -80,5 +80,5 @@
80
80
  ],
81
81
  "type": "module",
82
82
  "types": "./index.d.ts",
83
- "version": "0.36.1"
83
+ "version": "0.37.0"
84
84
  }
package/web-component.mjs CHANGED
@@ -1063,9 +1063,10 @@ function fillRandom(view) {
1063
1063
 
1064
1064
  // src/core/persistence.ts
1065
1065
  var log2 = logger.scope("persistence");
1066
- function createPersistence(widgetId, storage = defaultStorage) {
1067
- const prefix = `${BRAND.cssPrefix}.${widgetId}`;
1068
- const KEY_VISITOR = `${prefix}.visitorId`;
1066
+ function createPersistence(widgetId, storage = defaultStorage, deploymentId) {
1067
+ const scope = deploymentId ? `${widgetId}.${deploymentId}` : widgetId;
1068
+ const prefix = `${BRAND.cssPrefix}.${scope}`;
1069
+ const KEY_VISITOR = `${BRAND.cssPrefix}.visitorId`;
1069
1070
  const KEY_CONVERSATION = `${prefix}.conversationId`;
1070
1071
  const KEY_USER_PREFS = `${prefix}.userPrefs`;
1071
1072
  const KEY_PANEL_OPEN = `${prefix}.panelOpen`;
@@ -1083,14 +1084,14 @@ function createPersistence(widgetId, storage = defaultStorage) {
1083
1084
  return minted;
1084
1085
  },
1085
1086
  setVisitorId(id) {
1086
- log2.debug("setVisitorId (rebind)", { id, widgetId });
1087
+ log2.debug("setVisitorId (rebind)", { id, scope });
1087
1088
  storage.set(KEY_VISITOR, id);
1088
1089
  },
1089
1090
  loadConversationId() {
1090
1091
  return storage.get(KEY_CONVERSATION) ?? void 0;
1091
1092
  },
1092
1093
  saveConversationId(id) {
1093
- log2.trace("saveConversationId", { id, widgetId });
1094
+ log2.trace("saveConversationId", { id, scope });
1094
1095
  if (id) storage.set(KEY_CONVERSATION, id);
1095
1096
  else storage.remove(KEY_CONVERSATION);
1096
1097
  },
@@ -4122,7 +4123,7 @@ function themeIcon(mode) {
4122
4123
  return /* @__PURE__ */ jsx9(ThemeAutoIcon, {});
4123
4124
  }
4124
4125
  function localeCode(locale) {
4125
- return (locale.split("-")[0] || locale).toUpperCase();
4126
+ return (locale.split("-")[0] ?? locale).toUpperCase();
4126
4127
  }
4127
4128
  function HeaderActions({ panelProps, variant }) {
4128
4129
  const { options, panelSize, feedback, onClose, onClear, onExpand, onFullscreen, onPopOut, onSoundToggle } = panelProps;
@@ -6674,7 +6675,9 @@ import { jsx as jsx36, jsxs as jsxs31 } from "preact/jsx-runtime";
6674
6675
  var log16 = logger.scope("app");
6675
6676
  var p32 = BRAND.cssPrefix;
6676
6677
  function App({ options, hostElement, bus }) {
6677
- const [persistence] = useState13(() => createPersistence(options.widgetId, options.storage));
6678
+ const [persistence] = useState13(
6679
+ () => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
6680
+ );
6678
6681
  const [visitorId, setVisitorId] = useState13(() => persistence.getVisitorId());
6679
6682
  const initialSettings = persistence.loadUserPrefs();
6680
6683
  const [activeLocale, setActiveLocale] = useState13(() => initialSettings.locale ?? options.locale);
@@ -7862,7 +7865,7 @@ function createWidgetRuntime(params) {
7862
7865
  function resolveInitialHostMode(options) {
7863
7866
  if (options.mode === "standalone") return "standalone";
7864
7867
  if (options.mode === "inline") return "inline";
7865
- const persistence = createPersistence(options.widgetId, options.storage);
7868
+ const persistence = createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId);
7866
7869
  const { panelOpen, panelSize } = resolveInitialPanelState(
7867
7870
  options,
7868
7871
  currentViewportWidth(),
@@ -7948,7 +7951,7 @@ var ChatElement = class extends HTMLElement {
7948
7951
  position: hostPositionForMode(resolved.mode)
7949
7952
  });
7950
7953
  }
7951
- const persistence = createPersistence(resolved.widgetId, resolved.storage);
7954
+ const persistence = createPersistence(resolved.widgetId, resolved.storage, resolved.aiAgentDeploymentId);
7952
7955
  this.runtime = createWidgetRuntime({
7953
7956
  bus: this.bus,
7954
7957
  host: this.mountResult.hostElement,