@helpai/elements 0.26.0 → 0.27.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
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-2pMWV4oW.js';
1
+ export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-CcW_mx_i.js';
2
2
  import 'zod';
3
3
 
4
4
  /**
@@ -146,7 +146,7 @@ interface ConversationWelcome {
146
146
  suggestions?: ConversationSuggestion[];
147
147
  }
148
148
  /**
149
- * Response from `POST /ai-agent/handshake` — the widget's one mount-time
149
+ * Response from `POST /pai/handshake` — the widget's one mount-time
150
150
  * round-trip. Deliberately LIGHT: identity + deployment surface only
151
151
  * (config, agent persona, welcome, page-mode site/blocks, userPrefs).
152
152
  * The conversation THREAD is a separate, lazily-fetched read
@@ -901,9 +901,9 @@ interface PageContext {
901
901
  * like a CDN presign service).
902
902
  */
903
903
  interface Endpoints {
904
- /** File upload endpoint. Default: `'/ai-agent/upload-file'`. */
904
+ /** File upload endpoint. Default: `'/pai/upload-file'`. */
905
905
  upload?: string;
906
- /** Voice transcription endpoint. Default: `'/ai-agent/transcribe-audio'`. */
906
+ /** Voice transcription endpoint. Default: `'/pai/transcribe-audio'`. */
907
907
  transcribe?: string;
908
908
  /**
909
909
  * Form submission endpoint. Default: `'/submit-form'`. When any form
@@ -933,13 +933,14 @@ interface Endpoints {
933
933
  /** Section: anonymous owner-facing usage tracking. */
934
934
  interface TrackingOptions {
935
935
  /**
936
- * Master switch. Default `false` — tracking stays off until the
937
- * deployment (or the embedding page) explicitly turns it on.
936
+ * Master switch. Default `true` — the widget always fires; the data
937
+ * module gates ingestion per deployment server-side. Set `false`
938
+ * (deployment config or init) to silence the client entirely.
938
939
  */
939
940
  enabled?: boolean;
940
941
  /**
941
- * Pixel collector URL. Default: `${dataBaseUrl}/elements/px.gif`
942
- * (e.g. `https://help.ai/api/data/elements/px.gif`).
942
+ * Pixel collector URL. Default: `${dataBaseUrl}/pai/elements-px.gif`
943
+ * (e.g. `https://help.ai/api/data/pai/elements-px.gif`).
943
944
  */
944
945
  endpoint?: string;
945
946
  /**
@@ -1015,7 +1016,7 @@ interface ChatWidgetOptions {
1015
1016
  * Agent-API base (no trailing slash) — set it when the
1016
1017
  * `module-help-ai-agent-api` service is reached DIRECTLY (a standalone
1017
1018
  * local module, e.g. `http://localhost:3087`) instead of through the
1018
- * edge. Routes attach as-is (`${agentBaseUrl}/ai-agent/handshake`).
1019
+ * edge. Routes attach as-is (`${agentBaseUrl}/pai/handshake`).
1019
1020
  * Precedence: this option > derived from the main origin
1020
1021
  * (`${baseUrl}/api/agent`). Not server-pushable — the handshake already
1021
1022
  * travelled over it.
package/index.mjs CHANGED
@@ -476,13 +476,13 @@ var DEFAULT_FEATURES = {
476
476
  };
477
477
  var DEFAULT_FORMS = { list: [], byTrigger: {} };
478
478
  var DEFAULT_TRACKING = {
479
- enabled: false,
479
+ enabled: true,
480
480
  sampleRate: 1
481
481
  };
482
482
  var DEFAULT_ENDPOINTS = {
483
- upload: "/ai-agent/upload-file",
484
- transcribe: "/ai-agent/transcribe-audio",
485
- submitForm: "/submit-form"
483
+ upload: "/pai/upload-file",
484
+ transcribe: "/pai/transcribe-audio",
485
+ submitForm: "/pai/submit-form"
486
486
  };
487
487
  var DEFAULT_LAUNCHER = {
488
488
  variant: "circle",
@@ -615,9 +615,9 @@ function resolveTracking(overrides, dataBaseUrl) {
615
615
  const sampleRate = overrides?.sampleRate ?? DEFAULT_TRACKING.sampleRate;
616
616
  return {
617
617
  enabled: overrides?.enabled ?? DEFAULT_TRACKING.enabled,
618
- // The collector rides the data module — `${dataBaseUrl}/elements/px.gif`
619
- // (e.g. `https://help.ai/api/data/elements/px.gif`).
620
- endpoint: overrides?.endpoint ?? `${dataBaseUrl}/elements/px.gif`,
618
+ // The collector rides the data module — `${dataBaseUrl}/pai/elements-px.gif`
619
+ // (e.g. `https://help.ai/api/data/pai/elements-px.gif`).
620
+ endpoint: overrides?.endpoint ?? `${dataBaseUrl}/pai/elements-px.gif`,
621
621
  // Clamp instead of reject — a malformed rate must never turn a
622
622
  // disabled tracker on or crash resolve (no Zod on the IIFE path).
623
623
  sampleRate: Math.min(1, Math.max(0, Number.isFinite(sampleRate) ? sampleRate : 1)),
@@ -1253,63 +1253,61 @@ function parseWireDate(value) {
1253
1253
  }
1254
1254
  var DEFAULT_PATHS = {
1255
1255
  /** Conversation bootstrap. `POST` → deployment config + per-visitor state. */
1256
- handshake: "/ai-agent/handshake",
1256
+ handshake: "/pai/handshake",
1257
1257
  /** Send a message + stream the reply (SSE). `POST`. */
1258
- streamMessage: "/ai-agent/stream-message",
1258
+ streamMessage: "/pai/stream-message",
1259
1259
  /**
1260
1260
  * Resume an interrupted reply. `GET` (envelope rides as query params).
1261
1261
  * Stateless: the server re-streams the whole reply SSE again from the start —
1262
1262
  * there is NO `Last-Event-ID`. The client reconciles by id (`seenIds`), so
1263
1263
  * replayed events are skipped and only the continuation surfaces.
1264
1264
  */
1265
- streamResume: "/ai-agent/stream-resume",
1265
+ streamResume: "/pai/stream-resume",
1266
1266
  /** Abort the in-flight reply stream. `POST`. */
1267
- cancelStream: "/ai-agent/cancel-stream",
1267
+ cancelStream: "/pai/cancel-stream",
1268
1268
  /** List the visitor's conversations. `GET`. */
1269
- listConversations: "/ai-agent/list-conversations",
1269
+ listConversations: "/pai/list-conversations",
1270
1270
  /** Load one conversation's thread (messages + canContinue + suggestions). `GET ?conversationId=…`. */
1271
- listMessages: "/ai-agent/list-messages",
1271
+ listMessages: "/pai/list-messages",
1272
1272
  /**
1273
1273
  * Persist a user-driven settings change. POST `{ visitorId, userPrefs }` →
1274
1274
  * server persists, returns the merged authoritative copy. Fire-and-forget on
1275
1275
  * the client — a failure leaves the local cache valid; the next
1276
1276
  * `handshake()` reconciles.
1277
1277
  */
1278
- updateSettings: "/ai-agent/update-settings",
1278
+ updateSettings: "/pai/update-settings",
1279
1279
  /**
1280
1280
  * Mark a conversation read. POST `{ visitorId, conversationId }` → the server
1281
1281
  * records `lastReadAt = now` for that (visitor, conversation) and recomputes
1282
1282
  * `unreadCount` (returned on `/list-conversations`) accordingly. Fire-and-forget
1283
1283
  * on the client; a failure just leaves the badge until the next sync.
1284
1284
  */
1285
- markRead: "/ai-agent/mark-read",
1285
+ markRead: "/pai/mark-read",
1286
1286
  // ── Data API (module-help-ai-data-api, via `dataBaseUrl`) ─────────
1287
- /** All widget content via one filtered endpoint. `GET /content?tags=…`. */
1288
- content: "/content",
1289
1287
  /**
1290
- * Resolved form definitions for the deployment. `GET /forms` →
1291
- * `{ forms: FormDef[] }`. Fetched once at boot (in parallel with
1292
- * handshake); form gating waits for it. A failure is treated as
1293
- * "no forms" (non-fatal).
1288
+ * The data module's one ACTIVATION read. `GET
1289
+ * /pai/bootstrap?visitorId=…&conversationId=…`
1290
+ * `{ forms, formSubmissions }`: the deployment's resolved form
1291
+ * definitions plus the visitor's recorded submissions for the envelope's
1292
+ * conversation (chronological — they rebuild the timeline markers).
1293
+ * Also re-read with an explicit `conversationId` selector on a
1294
+ * history-pane thread switch. A failure is treated as "no forms, no
1295
+ * records" (non-fatal) — the chat works regardless.
1296
+ */
1297
+ bootstrap: "/pai/bootstrap",
1298
+ /**
1299
+ * All widget content via one filtered endpoint — content stays OUT of the
1300
+ * bootstrap because its reads are query-driven (`tags` / `categories` /
1301
+ * `ids` / `search` + pagination). `GET /pai/content?tags=…`.
1294
1302
  */
1295
- forms: "/forms",
1303
+ content: "/pai/content",
1296
1304
  /**
1297
1305
  * Form submission (the event-driven forms engine). POST `{ visitorId,
1298
1306
  * conversationId, formId, trigger, values, skipped? }` → record the form's answers
1299
1307
  * immediately, keyed by the same `visitorId` + `conversationId` the chat uses.
1300
1308
  * Overridable via `endpoints.submitForm`. Fire-and-forget; 404 is ignored.
1301
1309
  */
1302
- submitForm: "/submit-form",
1303
- /**
1304
- * Visitor interaction records for a conversation. `GET
1305
- * /activity?visitorId=…&conversationId=…` →
1306
- * `{ formSubmissions: FormSubmissionRecord[] }` (chronological). Replaces
1307
- * the former `formSubmissions` echo on the handshake / list-messages;
1308
- * deliberately generic — future visitor interaction records ride the same
1309
- * endpoint. A failure (e.g. 404 `AI_AGENT_PUBLIC_ACCESS_NOT_FOUND` when the
1310
- * deployment doesn't resolve) is treated as "no records" (non-fatal).
1311
- */
1312
- activity: "/activity"
1310
+ submitForm: "/pai/submit-form"
1313
1311
  };
1314
1312
  var CONTEXT_PARAM = "context";
1315
1313
  function buildSendMessageRequest(params) {
@@ -1598,38 +1596,26 @@ var AgentTransport = class {
1598
1596
  return { ...res, items };
1599
1597
  }
1600
1598
  /**
1601
- * Fetch the deployment's resolved form definitions. `GET /forms`
1602
- * (data-API). Replaces the former `config.forms` push on the handshake
1603
- * called once at boot, in parallel with `handshake`; form gating
1604
- * (pre-chat etc.) waits for it. Callers treat a thrown StreamError as
1605
- * "no forms" (non-fatal).
1606
- */
1607
- async listForms() {
1608
- log4.debug("listForms \u2192");
1609
- const res = await this.getJson(this.dataUrl(DEFAULT_PATHS.forms), "listForms");
1610
- const forms = res.forms ?? [];
1611
- log4.debug("listForms \u2190", { count: forms.length });
1612
- return { forms };
1613
- }
1614
- /**
1615
- * Fetch the visitor's recorded activity for a conversation — currently the
1616
- * form submissions that rebuild the collapsed "form submitted / skipped"
1617
- * timeline markers on resume. `GET /activity` (data-API); the
1618
- * envelope carries `visitorId` / `conversationId` as query params.
1619
- * `conversationId` here is an optional resource selector (a thread that may
1620
- * differ from the active conversation — the history-pane switch); when
1621
- * omitted, the envelope's active conversation applies. Callers treat a
1622
- * thrown StreamError (e.g. 404 on a deployment that doesn't resolve) as
1623
- * "no activity" (non-fatal).
1599
+ * The data module's ONE activation read. `GET /pai/bootstrap` (data-API)
1600
+ * the deployment's resolved form definitions + the visitor's recorded
1601
+ * form submissions for the envelope's conversation. The handshake
1602
+ * (agent-API) is completely independent of these surfaces.
1603
+ *
1604
+ * `conversationId` is an optional resource selector (a thread that may
1605
+ * differ from the active conversation — the history-pane switch re-reads
1606
+ * that thread's submissions); when omitted, the envelope's active
1607
+ * conversation applies. Callers treat a thrown StreamError (e.g. 404 on a
1608
+ * deployment that doesn't resolve) as "no forms, no records" (non-fatal).
1624
1609
  */
1625
- async getActivity(conversationId) {
1626
- const url = new URL(this.dataUrl(DEFAULT_PATHS.activity));
1610
+ async bootstrap(conversationId) {
1611
+ const url = new URL(this.dataUrl(DEFAULT_PATHS.bootstrap));
1627
1612
  if (conversationId) url.searchParams.set("conversationId", conversationId);
1628
- log4.debug("getActivity \u2192", { conversationId: conversationId ?? this.conversationId });
1629
- const res = await this.getJson(url.toString(), "getActivity");
1613
+ log4.debug("bootstrap \u2192", { conversationId: conversationId ?? this.conversationId });
1614
+ const res = await this.getJson(url.toString(), "bootstrap");
1615
+ const forms = res.forms ?? [];
1630
1616
  const formSubmissions = res.formSubmissions ?? [];
1631
- log4.debug("getActivity \u2190", { count: formSubmissions.length });
1632
- return { formSubmissions };
1617
+ log4.debug("bootstrap \u2190", { forms: forms.length, formSubmissions: formSubmissions.length });
1618
+ return { forms, formSubmissions };
1633
1619
  }
1634
1620
  async saveUserPrefs(userPrefs) {
1635
1621
  log4.debug("saveUserPrefs \u2192", {
@@ -1642,10 +1628,10 @@ var AgentTransport = class {
1642
1628
  return res;
1643
1629
  }
1644
1630
  get uploadPath() {
1645
- return this.opts.endpoints?.upload ?? "/ai-agent/upload-file";
1631
+ return this.opts.endpoints?.upload ?? "/pai/upload-file";
1646
1632
  }
1647
1633
  get transcribePath() {
1648
- return this.opts.endpoints?.transcribe ?? "/ai-agent/transcribe-audio";
1634
+ return this.opts.endpoints?.transcribe ?? "/pai/transcribe-audio";
1649
1635
  }
1650
1636
  get submitFormPath() {
1651
1637
  return this.opts.endpoints?.submitForm ?? DEFAULT_PATHS.submitForm;
@@ -1788,7 +1774,7 @@ var AgentTransport = class {
1788
1774
  }
1789
1775
  return false;
1790
1776
  }
1791
- /** Abort + fire-and-forget POST to `/ai-agent/cancel-stream`. Idempotent. */
1777
+ /** Abort + fire-and-forget POST to `/pai/cancel-stream`. Idempotent. */
1792
1778
  cancelStream(ctrl, conversationId) {
1793
1779
  if (ctrl.signal.aborted) return;
1794
1780
  log4.debug("cancel stream", { conversationId, visitorId: this.visitorId });
@@ -1898,7 +1884,7 @@ var AgentTransport = class {
1898
1884
  return await res.json();
1899
1885
  }
1900
1886
  /**
1901
- * Agent-API URL — resolves a `/ai-agent/*` path against the resolved
1887
+ * Agent-API URL — resolves a `/pai/*` path against the resolved
1902
1888
  * agent module base. Absolute URLs pass through unchanged.
1903
1889
  */
1904
1890
  url(pathOrUrl) {
@@ -6561,10 +6547,11 @@ function App({ options, hostElement, bus }) {
6561
6547
  },
6562
6548
  [messagesSig]
6563
6549
  );
6550
+ const dataBootRef = useRef9(null);
6564
6551
  const fetchFormMarkers = useCallback6(
6565
6552
  async (conversationId) => {
6566
6553
  try {
6567
- const { formSubmissions: subs } = await transport.getActivity(conversationId);
6554
+ const { formSubmissions: subs } = await (conversationId ? transport.bootstrap(conversationId) : dataBootRef.current ?? transport.bootstrap());
6568
6555
  const lastIndexByForm = /* @__PURE__ */ new Map();
6569
6556
  subs.forEach((rec, i) => lastIndexByForm.set(rec.formId, i));
6570
6557
  return subs.filter((rec, i) => !rec.skipped || lastIndexByForm.get(rec.formId) === i).map((rec, i) => ({
@@ -6575,7 +6562,7 @@ function App({ options, hostElement, bus }) {
6575
6562
  values: rec.values
6576
6563
  }));
6577
6564
  } catch (err) {
6578
- log16.debug("getActivity failed \u2014 no form markers (non-fatal)", { err });
6565
+ log16.debug("bootstrap failed \u2014 no form markers (non-fatal)", { err });
6579
6566
  return [];
6580
6567
  }
6581
6568
  },
@@ -6764,12 +6751,13 @@ function App({ options, hostElement, bus }) {
6764
6751
  }, []);
6765
6752
  useEffect17(() => {
6766
6753
  if (!activated) return;
6754
+ dataBootRef.current = transport.bootstrap();
6767
6755
  void (async () => {
6768
6756
  try {
6769
- const res = await transport.listForms();
6770
- setRemoteForms(resolveForms(res.forms));
6757
+ const res = await dataBootRef.current;
6758
+ setRemoteForms(resolveForms((res ?? { forms: [] }).forms));
6771
6759
  } catch (err) {
6772
- log16.debug("listForms failed \u2014 treating as no forms", { err });
6760
+ log16.debug("bootstrap failed \u2014 treating as no forms", { err });
6773
6761
  } finally {
6774
6762
  setFormsReady(true);
6775
6763
  }
@@ -7154,6 +7142,20 @@ function App({ options, hostElement, bus }) {
7154
7142
  },
7155
7143
  [transport, messagesSig, conversationIdSig, bus, options, persistence, refreshUnread, fetchFormMarkers]
7156
7144
  );
7145
+ const pendingOpenFormRef = useRef9(null);
7146
+ const openForm = useCallback6(
7147
+ (id) => {
7148
+ if (typeof id !== "string") return;
7149
+ if (formsReady) forms.fire("manual", id);
7150
+ else pendingOpenFormRef.current = id;
7151
+ },
7152
+ [formsReady, forms]
7153
+ );
7154
+ useEffect17(() => {
7155
+ if (!formsReady || !pendingOpenFormRef.current) return;
7156
+ forms.fire("manual", pendingOpenFormRef.current);
7157
+ pendingOpenFormRef.current = null;
7158
+ }, [formsReady, forms]);
7157
7159
  useEffect17(() => {
7158
7160
  const unsub = bindHostCommands(hostElement, {
7159
7161
  open: handleOpen,
@@ -7161,10 +7163,10 @@ function App({ options, hostElement, bus }) {
7161
7163
  expand: handleExpand,
7162
7164
  fullscreen: handleFullscreen,
7163
7165
  popout: handlePopOut,
7164
- openForm: (id) => forms.fire("manual", typeof id === "string" ? id : void 0)
7166
+ openForm
7165
7167
  });
7166
7168
  return unsub;
7167
- }, [hostElement, handleOpen, handleClose, handleExpand, handleFullscreen, handlePopOut, forms]);
7169
+ }, [hostElement, handleOpen, handleClose, handleExpand, handleFullscreen, handlePopOut, openForm]);
7168
7170
  const effectiveOptions = useMemo3(
7169
7171
  () => applyOptionOverrides(options, activeLocale, activeThemeMode, activeTextSize),
7170
7172
  [options, activeLocale, activeThemeMode, activeTextSize]
package/package.json CHANGED
@@ -80,5 +80,5 @@
80
80
  ],
81
81
  "type": "module",
82
82
  "types": "./index.d.ts",
83
- "version": "0.26.0"
83
+ "version": "0.27.0"
84
84
  }
package/schema.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-2pMWV4oW.js';
1
+ export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-CcW_mx_i.js';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
package/schema.json CHANGED
@@ -33,7 +33,7 @@
33
33
  "maxLength": 2048
34
34
  },
35
35
  "agentBaseUrl": {
36
- "description": "Full agent-API base — 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.",
36
+ "description": "Full agent-API base — 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: `/pai/handshake`). Precedence: this option > derived from the main origin (`${baseUrl}/api/agent`). Not server-pushable.",
37
37
  "type": "string",
38
38
  "minLength": 1,
39
39
  "maxLength": 2048
@@ -166,19 +166,19 @@
166
166
  "type": "object",
167
167
  "properties": {
168
168
  "upload": {
169
- "default": "/ai-agent/upload-file",
169
+ "default": "/pai/upload-file",
170
170
  "type": "string",
171
171
  "minLength": 1,
172
172
  "maxLength": 2048
173
173
  },
174
174
  "transcribe": {
175
- "default": "/ai-agent/transcribe-audio",
175
+ "default": "/pai/transcribe-audio",
176
176
  "type": "string",
177
177
  "minLength": 1,
178
178
  "maxLength": 2048
179
179
  },
180
180
  "submitForm": {
181
- "default": "/submit-form",
181
+ "default": "/pai/submit-form",
182
182
  "description": "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 — a 404 is ignored.",
183
183
  "type": "string",
184
184
  "minLength": 1,
@@ -194,8 +194,8 @@
194
194
  "description": "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.",
195
195
  "examples": [
196
196
  {
197
- "upload": "/ai-agent/upload-file",
198
- "transcribe": "/ai-agent/transcribe-audio"
197
+ "upload": "/pai/upload-file",
198
+ "transcribe": "/pai/transcribe-audio"
199
199
  },
200
200
  {
201
201
  "upload": "https://help.ai/uploads/presign"
@@ -1867,11 +1867,11 @@
1867
1867
  "type": "object",
1868
1868
  "properties": {
1869
1869
  "enabled": {
1870
- "description": "Master switch. Default `false` — no hits are sent until the deployment turns tracking on.",
1870
+ "description": "Master switch. Default `true` — the widget always fires; the data module gates ingestion per deployment server-side. Set `false` to silence the client entirely.",
1871
1871
  "type": "boolean"
1872
1872
  },
1873
1873
  "endpoint": {
1874
- "description": "Pixel collector URL. Default: `${dataBaseUrl}/elements/px.gif` (e.g. `https://help.ai/api/data/elements/px.gif`). Must be a full URL.",
1874
+ "description": "Pixel collector URL. Default: `${dataBaseUrl}/pai/elements-px.gif` (e.g. `https://help.ai/api/data/pai/elements-px.gif`). Must be a full URL.",
1875
1875
  "type": "string",
1876
1876
  "maxLength": 2048,
1877
1877
  "format": "uri"
@@ -3272,11 +3272,11 @@
3272
3272
  "type": "object",
3273
3273
  "properties": {
3274
3274
  "enabled": {
3275
- "description": "Master switch. Default `false` — no hits are sent until the deployment turns tracking on.",
3275
+ "description": "Master switch. Default `true` — the widget always fires; the data module gates ingestion per deployment server-side. Set `false` to silence the client entirely.",
3276
3276
  "type": "boolean"
3277
3277
  },
3278
3278
  "endpoint": {
3279
- "description": "Pixel collector URL. Default: `${dataBaseUrl}/elements/px.gif` (e.g. `https://help.ai/api/data/elements/px.gif`). Must be a full URL.",
3279
+ "description": "Pixel collector URL. Default: `${dataBaseUrl}/pai/elements-px.gif` (e.g. `https://help.ai/api/data/pai/elements-px.gif`). Must be a full URL.",
3280
3280
  "type": "string",
3281
3281
  "maxLength": 2048,
3282
3282
  "format": "uri"
package/schema.mjs CHANGED
@@ -569,9 +569,11 @@ var modulesSchema = z14.array(moduleSchema).max(4).describe(
569
569
  // src/schema/widget/tracking.ts
570
570
  import { z as z15 } from "zod";
571
571
  var trackingSchema = z15.object({
572
- enabled: z15.boolean().optional().describe("Master switch. Default `false` \u2014 no hits are sent until the deployment turns tracking on."),
572
+ enabled: z15.boolean().optional().describe(
573
+ "Master switch. Default `true` \u2014 the widget always fires; the data module gates ingestion per deployment server-side. Set `false` to silence the client entirely."
574
+ ),
573
575
  endpoint: z15.url().max(2048).optional().describe(
574
- "Pixel collector URL. Default: `${dataBaseUrl}/elements/px.gif` (e.g. `https://help.ai/api/data/elements/px.gif`). Must be a full URL."
576
+ "Pixel collector URL. Default: `${dataBaseUrl}/pai/elements-px.gif` (e.g. `https://help.ai/api/data/pai/elements-px.gif`). Must be a full URL."
575
577
  ),
576
578
  sampleRate: z15.number().min(0).max(1).optional().describe("Per-visitor sampling 0..1 (decided once per page load, keeping funnels intact). Default `1`."),
577
579
  token: z15.string().max(512).optional().describe(
@@ -585,16 +587,16 @@ var trackingSchema = z15.object({
585
587
 
586
588
  // src/schema/widget.ts
587
589
  var endpointsSchema = z16.object({
588
- upload: z16.string().min(1).max(2048).default("/ai-agent/upload-file"),
589
- transcribe: z16.string().min(1).max(2048).default("/ai-agent/transcribe-audio"),
590
- submitForm: z16.string().min(1).max(2048).default("/submit-form").describe(
590
+ upload: z16.string().min(1).max(2048).default("/pai/upload-file"),
591
+ transcribe: z16.string().min(1).max(2048).default("/pai/transcribe-audio"),
592
+ submitForm: z16.string().min(1).max(2048).default("/pai/submit-form").describe(
591
593
  "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."
592
594
  )
593
595
  }).loose().describe(
594
596
  "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."
595
597
  ).meta({
596
598
  examples: [
597
- { upload: "/ai-agent/upload-file", transcribe: "/ai-agent/transcribe-audio" },
599
+ { upload: "/pai/upload-file", transcribe: "/pai/transcribe-audio" },
598
600
  { upload: "https://help.ai/uploads/presign" },
599
601
  { submitForm: "https://crm.acme.com/leads" }
600
602
  ]
@@ -644,7 +646,7 @@ var connectionConfigSchema = z16.object({
644
646
  "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."
645
647
  ),
646
648
  agentBaseUrl: z16.string().min(1).max(2048).optional().describe(
647
- "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."
649
+ "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: `/pai/handshake`). Precedence: this option > derived from the main origin (`${baseUrl}/api/agent`). Not server-pushable."
648
650
  ),
649
651
  dataBaseUrl: z16.string().min(1).max(2048).optional().describe(
650
652
  "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`)."
@@ -687,7 +689,7 @@ var widgetSettingsSchema = z16.object({
687
689
  modules: modulesSchema.optional(),
688
690
  tracking: trackingSchema.optional()
689
691
  }).loose().describe(
690
- "Portal-configurable widget settings \u2014 fourteen sections, one per dashboard tab. The backend pushes this same shape on `/ai-agent/handshake` under `config`."
692
+ "Portal-configurable widget settings \u2014 fourteen sections, one per dashboard tab. The backend pushes this same shape on `/pai/handshake` under `config`."
691
693
  ).meta({
692
694
  examples: [
693
695
  { presentation: { mode: "floating", position: "bottom-right" }, theme: "auto" },