@helpai/elements 0.12.3 → 0.13.1

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 StartSessionResponse, W as WidgetConfig, d as WidgetConfigPartial, e as WidgetSettings, f as WidgetSettingsPartial } from './deployment-BUakRA3-.js';
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 StartSessionResponse, W as WidgetConfig, d as WidgetConfigPartial, e as WidgetSettings, f as WidgetSettingsPartial } from './deployment-Big98MYV.js';
2
2
  import 'zod';
3
3
 
4
4
  /**
@@ -40,7 +40,7 @@ interface ClientStorage {
40
40
  * populated {@link Strings} map. UI components then read `strings.send` as a
41
41
  * normal property access — no per-render lookup, no per-render allocation.
42
42
  */
43
- type StringKey = "launcherOpen" | "panelTitle" | "composerPlaceholder" | "send" | "stop" | "attach" | "micStart" | "micStop" | "micUnsupported" | "expand" | "collapse" | "fullscreen" | "exitFullscreen" | "resizeHandle" | "scrollToBottom" | "popOut" | "close" | "moreActions" | "soundOn" | "soundOff" | "language" | "theme" | "themeAuto" | "themeLight" | "themeDark" | "history" | "historyTitle" | "historyEmpty" | "historyLoading" | "historyNewChat" | "historyBack" | "messagesLoading" | "chatClosed" | "startNewConversation" | "dateToday" | "dateYesterday" | "dateLastWeek" | "dateOlder" | "newConversation" | "dropZone" | "attachmentTooLarge" | "attachmentTooMany" | "attachmentMimeRejected" | "errorRetry" | "errorGeneric" | "errorRateLimited" | "loading" | "thinking" | "thoughts" | "usedTool" | "collapseSidebar" | "expandSidebar" | "tabHome" | "tabMessages" | "tabHelp" | "tabNews" | "modulesEmpty" | "moduleBack" | "contentLoading" | "homeGreeting" | "homeGreetingNamed" | "homeGreetingLead" | "homeSearchPlaceholder" | "homeContentTitle" | "helpTitle" | "helpSearchPlaceholder" | "helpEmpty" | "helpLoading" | "helpSearchEmpty" | "newsTitle" | "newsEmpty" | "newsLoading" | "newsBack" | "newsPublishedAt";
43
+ type StringKey = "launcherOpen" | "panelTitle" | "composerPlaceholder" | "send" | "stop" | "attach" | "micStart" | "micStop" | "micUnsupported" | "expand" | "collapse" | "fullscreen" | "exitFullscreen" | "resizeHandle" | "scrollToBottom" | "popOut" | "close" | "moreActions" | "soundOn" | "soundOff" | "language" | "theme" | "themeAuto" | "themeLight" | "themeDark" | "history" | "historyTitle" | "historyEmpty" | "historyLoading" | "historyNewChat" | "historyBack" | "messagesLoading" | "chatClosed" | "startNewConversation" | "dateToday" | "dateYesterday" | "dateLastWeek" | "dateOlder" | "newConversation" | "dropZone" | "attachmentTooLarge" | "attachmentTooMany" | "attachmentMimeRejected" | "errorRetry" | "errorGeneric" | "errorRateLimited" | "loading" | "thinking" | "thoughts" | "usedTool" | "collapseSidebar" | "expandSidebar" | "intakeSubmit" | "intakeSkip" | "formRequired" | "formInvalidEmail" | "formInvalidTel" | "formInvalidUrl" | "formInvalidNumber" | "formTooShort" | "formTooLong" | "formNumberTooSmall" | "formNumberTooLarge" | "formPatternMismatch" | "formChooseAtLeast" | "formChooseAtMost" | "formOther" | "formOtherPlaceholder" | "inputRequired" | "inputSubmit" | "inputSkip" | "inputSubmitted" | "approvalRequired" | "approve" | "reject" | "approved" | "rejected" | "approvalReason" | "stepNoLongerActive" | "tabHome" | "tabMessages" | "tabHelp" | "tabNews" | "modulesEmpty" | "moduleBack" | "contentLoading" | "homeGreeting" | "homeGreetingNamed" | "homeGreetingLead" | "homeSearchPlaceholder" | "homeContentTitle" | "helpTitle" | "helpSearchPlaceholder" | "helpEmpty" | "helpLoading" | "helpSearchEmpty" | "newsTitle" | "newsEmpty" | "newsLoading" | "newsBack" | "newsPublishedAt";
44
44
  /** A partial map for one locale — what overrides look like on the wire. */
45
45
  type LocaleStrings = Partial<Record<StringKey, string>>;
46
46
  /**
@@ -111,6 +111,24 @@ interface UserPrefs {
111
111
  themeMode?: "auto" | "light" | "dark";
112
112
  }
113
113
 
114
+ /**
115
+ * A human-in-the-loop approval decision on a tool call. Mirrors AI SDK v6's
116
+ * `ToolUIPart.approval`: `id` correlates the request ↔ response; `approved`
117
+ * is filled once the user decides; `reason` is an optional note.
118
+ */
119
+ interface ToolApproval {
120
+ id: string;
121
+ approved?: boolean;
122
+ reason?: string;
123
+ }
124
+ /**
125
+ * Lifecycle of a tool part. `input` — args streaming. `awaiting` —
126
+ * server-executed tool waiting on output. `awaiting-input` — the ask-input
127
+ * tool waiting on the user's inline-form answer. `awaiting-approval` — a gated
128
+ * action waiting on approve/reject. `output` — resolved. `error` — failed.
129
+ */
130
+ type ToolState = "input" | "awaiting" | "awaiting-input" | "awaiting-approval" | "output" | "error";
131
+
114
132
  /** A tool reference on the wire: `{ code, config }`. `config` is opaque. */
115
133
  interface ToolRef {
116
134
  code: string;
@@ -141,6 +159,22 @@ type WirePart = {
141
159
  fileId?: string;
142
160
  /** Size in bytes. */
143
161
  fileSize?: number;
162
+ } | {
163
+ /**
164
+ * A tool call on the wire. Carries the resolved result up to the backend
165
+ * on a HITL re-POST: the ask-input answer rides in `output`, an approval
166
+ * decision in `approval`. Sent up only for parts the user has acted on
167
+ * (state `output`/`error`/`awaiting-approval` with a decision); in-flight
168
+ * tool parts are not re-serialized. Aligns with AI SDK v6 tool parts.
169
+ */
170
+ type: "tool";
171
+ toolCallId: string;
172
+ toolName: string;
173
+ state: ToolState;
174
+ input?: unknown;
175
+ output?: unknown;
176
+ errorText?: string;
177
+ approval?: ToolApproval;
144
178
  };
145
179
  /** One-shot bot persona shown in the panel header. */
146
180
  interface SessionAgent {
@@ -334,6 +368,12 @@ interface FeatureFlags {
334
368
  * format always uses the rich shape.
335
369
  */
336
370
  tools?: Array<string | ToolRef>;
371
+ /**
372
+ * Render human-in-the-loop tool UI — the inline ask-input form and the
373
+ * approve/reject controls for gated tools. Default `true`. Set `false` to
374
+ * suppress them (the wire still carries the signals; they just won't show).
375
+ */
376
+ humanInLoop?: boolean;
337
377
  }
338
378
  /**
339
379
  * Client-side attachment limits. Server enforcement is still required —
@@ -413,6 +453,83 @@ interface FeedbackOptions {
413
453
  haptics?: HapticsOptions;
414
454
  }
415
455
 
456
+ /**
457
+ * Intake form + shared form-field runtime config types — framework-free
458
+ * mirror of `src/schema/widget/intake.ts`. The IIFE runtime path has no
459
+ * Zod, so these plain interfaces are what the resolver + form engine consume.
460
+ *
461
+ * The same {@link FormField} shape powers two surfaces:
462
+ * 1. the deterministic pre-chat **intake** gate (this section), and
463
+ * 2. the AI-driven **ask-input tool** (`src/ui/tool-ask-input.tsx`), which
464
+ * maps a wire ask-input request onto `FormField[]` and reuses the same
465
+ * `<DynamicForm>` renderer.
466
+ */
467
+ /** A renderable field type. `multiselect` collects an array of values. */
468
+ type FieldType = "text" | "email" | "tel" | "url" | "number" | "textarea" | "select" | "radio" | "checkbox" | "multiselect";
469
+ /** One choice for `select` / `radio` / `multiselect` fields. */
470
+ interface FieldOption {
471
+ value: string;
472
+ /** Display text; falls back to `value`. */
473
+ label?: string;
474
+ description?: string;
475
+ }
476
+ /** Validation constraints applied client-side (the backend still validates). */
477
+ interface FieldValidation {
478
+ /** Regex source string (anchored as written) — text-like fields. */
479
+ pattern?: string;
480
+ minLength?: number;
481
+ maxLength?: number;
482
+ /** Numeric range — `number` fields. */
483
+ min?: number;
484
+ max?: number;
485
+ /** Selection-count bounds — `multiselect` fields. */
486
+ minSelections?: number;
487
+ maxSelections?: number;
488
+ }
489
+ /** One field in a form (intake or ask-input). */
490
+ interface FormField {
491
+ /** Stable key the value is recorded under (e.g. `email`). */
492
+ name: string;
493
+ label: string;
494
+ type: FieldType;
495
+ placeholder?: string;
496
+ required?: boolean;
497
+ /** Pre-filled value (string for scalars; comma-joined for `multiselect`). */
498
+ defaultValue?: string;
499
+ /** Choices for `select` / `radio` / `multiselect`. */
500
+ options?: FieldOption[];
501
+ validation?: FieldValidation;
502
+ /** `select`/`radio`/`multiselect` — allow a free-text "Other" answer. */
503
+ allowOther?: boolean;
504
+ /** Small helper line under the field. */
505
+ validationHint?: string;
506
+ }
507
+ /**
508
+ * Section: pre-chat intake form. A **blocking gate** — when `enabled` and not
509
+ * yet completed, the user must submit (or skip, if `skippable`) before the
510
+ * composer unlocks. Captured values are persisted per-device and attached to
511
+ * the first request. Off by default — existing deployments are unchanged.
512
+ */
513
+ interface IntakeOptions {
514
+ enabled?: boolean;
515
+ title?: string;
516
+ description?: string;
517
+ fields?: FormField[];
518
+ submitLabel?: string;
519
+ /** Allow dismissing the whole form without answering. Default `false`. */
520
+ skippable?: boolean;
521
+ }
522
+ /** Fully-resolved intake config exposed on {@link ResolvedOptions}. */
523
+ interface ResolvedIntake {
524
+ /** Effective only when there is at least one valid field. */
525
+ enabled: boolean;
526
+ title?: string;
527
+ description?: string;
528
+ fields: FormField[];
529
+ submitLabel?: string;
530
+ skippable: boolean;
531
+ }
532
+
416
533
  /**
417
534
  * Launcher (floating-mode FAB) + the pre-engagement callout bubble.
418
535
  * Inputs are option-bag shaped; the resolved variant lives in `widget.ts`.
@@ -782,6 +899,14 @@ interface Endpoints {
782
899
  upload?: string;
783
900
  /** Voice transcription endpoint. Default: `'/ai/agent/transcribe-audio'`. */
784
901
  transcribe?: string;
902
+ /**
903
+ * Pre-chat intake submission endpoint. Default: `'/ai/agent/intake'`. When the
904
+ * intake gate is completed, the widget POSTs the captured values here
905
+ * (fire-and-forget) so the lead is recorded immediately — keyed by the same
906
+ * `visitorId` + `sessionId` the conversation will use. Optional: a backend
907
+ * that doesn't implement it just 404s and the submission is ignored.
908
+ */
909
+ intake?: string;
785
910
  }
786
911
 
787
912
  /**
@@ -852,6 +977,8 @@ interface ChatWidgetOptions {
852
977
  footer?: FooterOptions;
853
978
  /** Capability flags (file upload, voice mode, tools). Server-pushable. */
854
979
  features?: FeatureFlags;
980
+ /** Pre-chat intake form (lead/sales capture). Blocking gate. Server-pushable. */
981
+ intake?: IntakeOptions;
855
982
  /** Messenger modules (Chat / Home / Messages / Help / News tabs). Server-pushable. */
856
983
  modules?: ModulesOptions;
857
984
  /**
@@ -899,6 +1026,8 @@ interface ResolvedOptions {
899
1026
  features: Required<Omit<FeatureFlags, "tools">> & {
900
1027
  tools?: Array<string | ToolRef>;
901
1028
  };
1029
+ /** Resolved pre-chat intake form — `enabled` only when it has ≥1 valid field. */
1030
+ intake: ResolvedIntake;
902
1031
  endpoints: Required<Endpoints>;
903
1032
  attachments: Required<Pick<AttachmentLimits, "maxBytes" | "maxCount">> & {
904
1033
  accept: string;
@@ -976,6 +1105,7 @@ interface ServerConfig {
976
1105
  i18n?: I18nOptions;
977
1106
  footer?: FooterOptions;
978
1107
  features?: FeatureFlags;
1108
+ intake?: IntakeOptions;
979
1109
  modules?: ModulesOptions;
980
1110
  endpoints?: Endpoints;
981
1111
  }
@@ -1075,6 +1205,17 @@ interface EventMap {
1075
1205
  toggleHistory: {
1076
1206
  view: "chat" | "history";
1077
1207
  };
1208
+ /** Pre-chat intake form completed (or skipped → empty values). */
1209
+ intakeSubmit: Record<string, string>;
1210
+ /** User answered an ask-input tool request (re-POST follows). */
1211
+ toolResult: {
1212
+ toolCallId: string;
1213
+ };
1214
+ /** User approved / rejected a gated tool call (re-POST follows). */
1215
+ toolDecision: {
1216
+ toolCallId: string;
1217
+ approved: boolean;
1218
+ };
1078
1219
  /** Files attached (drag-drop, file picker, paste). */
1079
1220
  attach: {
1080
1221
  count: number;