@helpai/elements 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, L as Link, S as ServerConfig, b as SiteConfig, c as StartConversationResponse, W as WidgetConfig, d as WidgetConfigPartial, e as WidgetSettings, f as WidgetSettingsPartial } from './deployment-BP2axIFu.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-2pMWV4oW.js';
2
2
  import 'zod';
3
3
 
4
4
  /**
@@ -113,94 +113,11 @@ interface UserPrefs {
113
113
  textSize?: "small" | "normal" | "large";
114
114
  }
115
115
 
116
- /**
117
- * A human-in-the-loop approval decision on a tool call. Mirrors AI SDK v6's
118
- * `ToolUIPart.approval`: `id` correlates the request ↔ response; `approved`
119
- * is filled once the user decides; `reason` is an optional note.
120
- */
121
- interface ToolApproval {
122
- id: string;
123
- approved?: boolean;
124
- reason?: string;
125
- }
126
- /**
127
- * Lifecycle of a tool part. `input` — args streaming. `awaiting` —
128
- * server-executed tool waiting on output. `awaiting-input` — the ask-input
129
- * tool waiting on the user's inline-form answer. `awaiting-approval` — a gated
130
- * action waiting on approve/reject. `output` — resolved. `error` — failed.
131
- */
132
- type ToolState = "input" | "awaiting" | "awaiting-input" | "awaiting-approval" | "output" | "error";
133
-
134
116
  /** A tool reference on the wire: `{ code, config }`. `config` is opaque. */
135
117
  interface ToolRef {
136
118
  code: string;
137
119
  config?: Record<string, unknown>;
138
120
  }
139
- interface WireMessage {
140
- id: string;
141
- role: "user" | "assistant" | "system";
142
- parts: WirePart[];
143
- /**
144
- * ISO-8601 timestamp the message was created (a serialized Mongo ISODate,
145
- * e.g. `2026-06-10T07:50:55.816Z`) — every wire date uses this format.
146
- * Optional so older backends still parse; when present, the widget shows
147
- * the real send time (and groups messages by day) on reload instead of
148
- * falling back to "now". Parse with {@link parseWireDate}.
149
- */
150
- createdAt?: string;
151
- }
152
- type WirePart = {
153
- type: "text";
154
- text: string;
155
- } | {
156
- type: "file";
157
- /** Canonical URL. May be a custom scheme (e.g. `library-id://<id>`). */
158
- url: string;
159
- mediaType: string;
160
- /** Original filename as uploaded. */
161
- filename?: string;
162
- /** Opaque id from the upload response — lets the backend dedupe + cache. */
163
- fileId?: string;
164
- /** Size in bytes. */
165
- fileSize?: number;
166
- } | {
167
- /**
168
- * A tool call on the wire. Carries the resolved result up to the backend
169
- * on a HITL re-POST: the ask-input answer rides in `output`, an approval
170
- * decision in `approval`. Sent up only for parts the user has acted on
171
- * (state `output`/`error`/`awaiting-approval` with a decision); in-flight
172
- * tool parts are not re-serialized. Aligns with AI SDK v6 tool parts.
173
- */
174
- type: "tool";
175
- toolCallId: string;
176
- toolName: string;
177
- state: ToolState;
178
- input?: unknown;
179
- output?: unknown;
180
- errorText?: string;
181
- approval?: ToolApproval;
182
- };
183
- /**
184
- * One recorded form submission, returned on `/ai/agent/start-conversation`
185
- * (alongside `messages`) so the widget can re-place the "form submitted /
186
- * skipped" marker at its chronological spot in the timeline.
187
- */
188
- interface FormSubmissionRecord {
189
- formId: string;
190
- /** The trigger kind that surfaced the form. */
191
- trigger: string;
192
- /** True when the visitor skipped instead of answering. */
193
- skipped?: boolean;
194
- /** ISO-8601 — same format + name as {@link WireMessage.createdAt}. */
195
- createdAt?: string;
196
- /**
197
- * The visitor's own answers, echoed back so the submitted marker can offer
198
- * a read-only review after a reload. Scoped to the same `visitorId` that
199
- * submitted them — this is the visitor seeing their own data, independent
200
- * of `submit.toContext` (which governs mirroring into request context).
201
- */
202
- values?: Record<string, string>;
203
- }
204
121
  /** One-shot bot persona shown in the panel header. */
205
122
  interface ConversationAgent {
206
123
  name: string;
@@ -229,8 +146,12 @@ interface ConversationWelcome {
229
146
  suggestions?: ConversationSuggestion[];
230
147
  }
231
148
  /**
232
- * Response from `POST /ai/agent/start-conversation`. Every field is optional so the
233
- * backend can opt into surfaces incrementally.
149
+ * Response from `POST /ai-agent/handshake` the widget's one mount-time
150
+ * round-trip. Deliberately LIGHT: identity + deployment surface only
151
+ * (config, agent persona, welcome, page-mode site/blocks, userPrefs).
152
+ * The conversation THREAD is a separate, lazily-fetched read
153
+ * (`GET /conversation`) that only runs once the widget is activated
154
+ * (opened) — a closed launcher costs the page exactly one request.
234
155
  *
235
156
  * The `userPrefs` field (when present) is the server's authoritative
236
157
  * copy of per-visitor preferences — the client should adopt it and update
@@ -238,14 +159,13 @@ interface ConversationWelcome {
238
159
  * widget in French when they open it on their laptop (assuming the same
239
160
  * `visitorId`, e.g. via authenticated conversation — out of scope for v1).
240
161
  */
241
- interface StartConversationResponse {
162
+ interface HandshakeResponse {
242
163
  /**
243
164
  * Public runtime conversation id. The widget mints this UUIDv7 and the backend
244
165
  * validates that it belongs to the public deployment + visitor.
245
166
  */
246
167
  conversationId: string;
247
168
  visitorId?: string;
248
- canContinue?: boolean;
249
169
  /** Bot persona in the panel header (name, avatar, status). */
250
170
  agent?: ConversationAgent;
251
171
  /** Initial assistant messages + quick-reply chips. */
@@ -261,14 +181,6 @@ interface StartConversationResponse {
261
181
  site?: Record<string, unknown>;
262
182
  /** Page-mode sidebar blocks (navigation, link cards). Backend ships it whenever the deployment renders the page-shell sidebar. */
263
183
  blocks?: Record<string, unknown>;
264
- messages?: WireMessage[];
265
- /**
266
- * Form submissions recorded for this conversation (via
267
- * `/ai/agent/submit-form`), returned like `messages` so the widget can
268
- * reconstruct the timeline on resume — each renders as a collapsed
269
- * "form submitted" marker at its chronological position.
270
- */
271
- formSubmissions?: FormSubmissionRecord[];
272
184
  /**
273
185
  * Server's authoritative copy of the visitor's preferences. When present,
274
186
  * client adopts it (overrides local cache) and re-applies it to the UI
@@ -320,7 +232,7 @@ type Position = "bottom-right" | "bottom-left" | "top-right" | "top-left";
320
232
  * `"12px"` horizontal — restore the legacy full-edge
321
233
  * slab with `size: { width: "100vw", height: "100vh", inset: "0" }`.
322
234
  *
323
- * Page mode reads `site` and `blocks` from the start-conversation response.
235
+ * Page mode reads `site` and `blocks` from the handshake response.
324
236
  */
325
237
  type Mode = "floating" | "inline" | "standalone" | "page" | "modal" | "drawer";
326
238
  /** End-user text-size preference — scales the whole type ramp. */
@@ -590,7 +502,7 @@ interface FormDef {
590
502
  * answers. Default `true`. Set `false` to keep the marker plain — e.g.
591
503
  * sensitive answers that shouldn't linger on screen (pairs with
592
504
  * `mirrorToContext: false`; the backend should also omit `values` from the
593
- * `formSubmissions` echo for such forms).
505
+ * `/activity` records for such forms).
594
506
  */
595
507
  reviewable?: boolean;
596
508
  }
@@ -698,7 +610,7 @@ interface LauncherOptions {
698
610
  *
699
611
  * `modules` is an ordered list of tabs; each picks a UI `layout`, optional
700
612
  * content `contentTags` (the scope passed as the `tags` filter to
701
- * `GET /ai/agent/content`), and a translatable `label`.
613
+ * `GET /content`), and a translatable `label`.
702
614
  */
703
615
  /** The UI layouts a tab can render with. `chat` is the conversation; the rest render content. */
704
616
  type ModuleLayout = "chat" | "home" | "help" | "news";
@@ -982,17 +894,19 @@ interface PageContext {
982
894
  [key: string]: string | number | boolean | undefined;
983
895
  }
984
896
  /**
985
- * Override the HTTP endpoints the widget calls. Paths are appended to
986
- * `baseUrl`. Absolute URLs also work (useful when the upload endpoint
987
- * lives on a different origin like a CDN presign service).
897
+ * Override the HTTP endpoints the widget calls. `upload` / `transcribe`
898
+ * paths are appended to the agent base (`${baseUrl}/api/agent`);
899
+ * `submitForm` is appended to the data base (`dataBaseUrl`). Absolute URLs
900
+ * also work (useful when the upload endpoint lives on a different origin
901
+ * like a CDN presign service).
988
902
  */
989
903
  interface Endpoints {
990
- /** File upload endpoint. Default: `'/ai/agent/upload-file'`. */
904
+ /** File upload endpoint. Default: `'/ai-agent/upload-file'`. */
991
905
  upload?: string;
992
- /** Voice transcription endpoint. Default: `'/ai/agent/transcribe-audio'`. */
906
+ /** Voice transcription endpoint. Default: `'/ai-agent/transcribe-audio'`. */
993
907
  transcribe?: string;
994
908
  /**
995
- * Form submission endpoint. Default: `'/ai/agent/submit-form'`. When any form
909
+ * Form submission endpoint. Default: `'/submit-form'`. When any form
996
910
  * (a pre-chat lead capture, a CSAT survey, etc.) is completed, the widget POSTs
997
911
  * the captured values here (fire-and-forget), keyed by the same `visitorId` +
998
912
  * `conversationId` the conversation uses; the payload carries `formId` + `trigger`
@@ -1024,8 +938,8 @@ interface TrackingOptions {
1024
938
  */
1025
939
  enabled?: boolean;
1026
940
  /**
1027
- * Pixel collector URL. Default: `https://t.<brand domain>/api/ai-elements/px.gif`
1028
- * (e.g. `https://t.help.ai/api/ai-elements/px.gif`).
941
+ * Pixel collector URL. Default: `${dataBaseUrl}/elements/px.gif`
942
+ * (e.g. `https://help.ai/api/data/elements/px.gif`).
1029
943
  */
1030
944
  endpoint?: string;
1031
945
  /**
@@ -1036,7 +950,7 @@ interface TrackingOptions {
1036
950
  /**
1037
951
  * Anti-forgery token, echoed as `tk=` on every hit. **Server-issued,
1038
952
  * never set by hand** — the backend mints it in the
1039
- * `/start-conversation` response (HMAC over `pk`/`vid`/expiry with a
953
+ * `/handshake` response (HMAC over `pk`/`vid`/expiry with a
1040
954
  * server-side secret; see `docs/api/tracking-collector.md`) and the
1041
955
  * collector verifies it statelessly. Opaque to the client.
1042
956
  */
@@ -1053,7 +967,7 @@ interface ResolvedTracking {
1053
967
  /**
1054
968
  * The three composing roots: raw input ({@link ChatWidgetOptions}),
1055
969
  * post-normalisation runtime shape ({@link ResolvedOptions}), and the
1056
- * subset the server can push back via `/start-conversation` ({@link
970
+ * subset the server can push back via `/handshake` ({@link
1057
971
  * ServerConfig}).
1058
972
  *
1059
973
  * Internal modules always depend on `ResolvedOptions`. The raw shape
@@ -1090,8 +1004,33 @@ interface ChatWidgetOptions {
1090
1004
  publicKey?: string;
1091
1005
  /** Deployment ID (UUID). Sent as `x-ai-agent-deployment-id`. */
1092
1006
  aiAgentDeploymentId?: string;
1093
- /** Backend origin (no trailing slash). Defaults to the brand's default. */
1007
+ /**
1008
+ * MAIN site origin (no trailing slash, e.g. `https://help.ai`). The API
1009
+ * modules derive from it — the production edge mounts the agent API at
1010
+ * `${baseUrl}/api/agent` and the data API at `${baseUrl}/api/data`.
1011
+ * Defaults to the brand's origin.
1012
+ */
1094
1013
  baseUrl?: string;
1014
+ /**
1015
+ * Agent-API base (no trailing slash) — set it when the
1016
+ * `module-help-ai-agent-api` service is reached DIRECTLY (a standalone
1017
+ * local module, e.g. `http://localhost:3087`) instead of through the
1018
+ * edge. Routes attach as-is (`${agentBaseUrl}/ai-agent/handshake`).
1019
+ * Precedence: this option > derived from the main origin
1020
+ * (`${baseUrl}/api/agent`). Not server-pushable — the handshake already
1021
+ * travelled over it.
1022
+ */
1023
+ agentBaseUrl?: string;
1024
+ /**
1025
+ * Data-API base (no trailing slash) — the `module-help-ai-data-api`
1026
+ * service serving content, form definitions, and form submissions at
1027
+ * root-level paths (`/content`, `/forms`, `/activity`, `/submit-form`).
1028
+ * Set it for a standalone local module (e.g. `http://localhost:3106`).
1029
+ * Precedence: this option > server-pushed `config.dataBaseUrl` > derived
1030
+ * from the main origin (`${baseUrl}/api/data`, e.g.
1031
+ * `https://help.ai/api/data`).
1032
+ */
1033
+ dataBaseUrl?: string;
1095
1034
  /** Host-asserted, informational end-user context (untrusted; not auth). */
1096
1035
  userContext?: UserContext;
1097
1036
  /** Host-asserted, informational page/visit context (untrusted; `area`, url, …). */
@@ -1146,6 +1085,10 @@ interface ResolvedOptions {
1146
1085
  publicKey?: string;
1147
1086
  aiAgentDeploymentId?: string;
1148
1087
  baseUrl: string;
1088
+ /** Resolved agent-API base — see {@link ChatWidgetOptions.agentBaseUrl}. */
1089
+ agentBaseUrl: string;
1090
+ /** Resolved data-API base — see {@link ChatWidgetOptions.dataBaseUrl}. */
1091
+ dataBaseUrl: string;
1149
1092
  userContext?: UserContext;
1150
1093
  pageContext?: PageContext;
1151
1094
  position: Position;
@@ -1232,13 +1175,19 @@ interface ResolvedOptions {
1232
1175
  onError?: ChatWidgetOptions["onError"];
1233
1176
  }
1234
1177
  /**
1235
- * Shape of the server-pushed `widget` object in `StartConversationResponse`.
1178
+ * Shape of the server-pushed `widget` object in `HandshakeResponse`.
1236
1179
  *
1237
1180
  * Matches a subset of {@link ChatWidgetOptions} — anything the server can
1238
1181
  * reasonably dictate (UI, behaviour, routing). Callbacks (`onMessage` etc.)
1239
1182
  * and the public key are deliberately excluded — those are client concerns.
1183
+ *
1184
+ * Form definitions no longer ride this config: the widget fetches them from
1185
+ * the data-API (`GET /forms`). A stale backend still pushing
1186
+ * `config.forms` is ignored.
1240
1187
  */
1241
1188
  interface ServerConfig {
1189
+ /** Data-API base override — adopted only when the host didn't set one. */
1190
+ dataBaseUrl?: string;
1242
1191
  presentation?: PresentationOptions;
1243
1192
  behavior?: BehaviorOptions;
1244
1193
  theme?: ThemePreference | ThemeOverrides;
@@ -1249,7 +1198,6 @@ interface ServerConfig {
1249
1198
  i18n?: I18nOptions;
1250
1199
  footer?: FooterOptions;
1251
1200
  features?: FeatureFlags;
1252
- forms?: FormsOptions;
1253
1201
  modules?: ModulesOptions;
1254
1202
  tracking?: TrackingOptions;
1255
1203
  endpoints?: Endpoints;
@@ -1401,18 +1349,18 @@ interface EventMap {
1401
1349
  /** An unhandled error occurred somewhere in the transport or UI. */
1402
1350
  error: unknown;
1403
1351
  /** Connect bootstrap succeeded. Payload is the typed server response. */
1404
- conversationStarted: StartConversationResponse;
1352
+ handshake: HandshakeResponse;
1405
1353
  /**
1406
1354
  * Server rebound the `visitorId` — e.g. the client-minted id
1407
1355
  * conflicted with an existing record, was expired, or otherwise
1408
1356
  * rejected, and the server returned a fresh one in the
1409
- * `/start-conversation` response. The widget has already adopted the new
1357
+ * `/handshake` response. The widget has already adopted the new
1410
1358
  * id and persisted it; this event is informational so host pages
1411
1359
  * can re-link analytics / external systems that pinned the
1412
1360
  * previous value.
1413
1361
  *
1414
1362
  * `reason` is the server's explanation, when provided
1415
- * (`rebind.visitorId` in the start-conversation response). Common values:
1363
+ * (`rebind.visitorId` in the handshake response). Common values:
1416
1364
  * `"conflict"` / `"expired"` / `"invalid"`. May be `undefined` if
1417
1365
  * the server didn't include a `rebind` block.
1418
1366
  */
@@ -1541,7 +1489,7 @@ interface ChatWidgetInstance {
1541
1489
  expand: () => void;
1542
1490
  /**
1543
1491
  * Open the widget in a new browser tab at `behavior.popOutUrl`
1544
- * (mount option / start-conversation-pushable), or the brand's
1492
+ * (mount option / handshake-pushable), or the brand's
1545
1493
  * `BRAND.standaloneUrl` build-time default. Carries the active
1546
1494
  * `chat` + `widgetId` as query params. No-ops when the resolved
1547
1495
  * URL is empty.
@@ -1557,7 +1505,7 @@ interface ChatWidgetInstance {
1557
1505
  * Subscribe to a lifecycle event. Returns an `off` function. See
1558
1506
  * {@link EventMap} for the full set + payload shapes — currently
1559
1507
  * `open | close | message | error | expand | fullscreen | popOut |
1560
- * conversationStarted | localeChange`.
1508
+ * handshake | localeChange`.
1561
1509
  */
1562
1510
  on: <E extends EventName>(name: E, fn: (payload: EventMap[E]) => void) => () => void;
1563
1511
  /**
@@ -1578,7 +1526,7 @@ interface ChatWidgetInstance {
1578
1526
  * ```
1579
1527
  */
1580
1528
  setUserContext: (userContext: UserContext) => void;
1581
- /** Clear the end-user context (e.g. on logout) and re-start-conversation anonymously. */
1529
+ /** Clear the end-user context (e.g. on logout) and re-handshake anonymously. */
1582
1530
  clearUserContext: () => void;
1583
1531
  /**
1584
1532
  * Set / merge the host-asserted page/visit context (`area`, `url`, `path`,
@@ -1592,7 +1540,7 @@ interface ChatWidgetInstance {
1592
1540
  * ```
1593
1541
  */
1594
1542
  setPageContext: (pageContext: PageContext) => void;
1595
- /** Clear the page/visit context and re-start-conversation. */
1543
+ /** Clear the page/visit context and re-handshake. */
1596
1544
  clearPageContext: () => void;
1597
1545
  /**
1598
1546
  * Set the runtime log level. Accepts `"off"` / `"error"` / `"warn"` /