@waniwani/sdk 0.15.1 → 0.16.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.
@@ -62,7 +62,14 @@ interface KbClient {
62
62
  sources(): Promise<KbSource[]>;
63
63
  }
64
64
 
65
- type EventType = "session.started" | "page.viewed" | "tool.called" | "quote.requested" | "quote.succeeded" | "quote.failed" | "link.clicked" | "purchase.completed" | "widget_render" | "widget_click" | "widget_link_click" | "widget_error" | "widget_scroll" | "widget_form_field" | "widget_form_submit" | "user.identified" | "price_shown" | "prices_compared" | "option_selected" | "lead_qualified" | "converted";
65
+ /**
66
+ * Every event name in the typed taxonomy, as a runtime list. Single source of
67
+ * truth for {@link EventType} and for surfaces that need to recognize
68
+ * first-class names at runtime (the widget transport passes these through
69
+ * verbatim instead of namespacing them as custom widget events).
70
+ */
71
+ declare const EVENT_TYPES: readonly ["session.started", "page.viewed", "tool.called", "quote.requested", "quote.succeeded", "quote.failed", "link.clicked", "purchase.completed", "widget_render", "user.identified", "price_shown", "prices_compared", "option_selected", "lead_qualified", "converted"];
72
+ type EventType = (typeof EVENT_TYPES)[number];
66
73
  /**
67
74
  * Properties for `page.viewed` — emitted once when the chat widget initializes
68
75
  * on a host page (the top of the funnel). Attributed to the anonymous
@@ -136,8 +143,6 @@ interface LeadQualifiedProperties {
136
143
  email?: string;
137
144
  /** The lead's name, if known. */
138
145
  name?: string;
139
- /** Acquisition source of the lead (e.g. "newsletter"). */
140
- source?: string;
141
146
  }
142
147
  interface ConvertedProperties {
143
148
  amount: number;
@@ -162,6 +167,13 @@ interface TrackingContext {
162
167
  requestId?: string;
163
168
  correlationId?: string;
164
169
  externalUserId?: string;
170
+ /**
171
+ * Anonymous visitor id (the analytics "device id"). Counts as identity on
172
+ * its own: the ingest API accepts `sessionId`, `externalUserId`, or
173
+ * `visitorId`. The chat widget uses it for pre-session events like
174
+ * `page.viewed`.
175
+ */
176
+ visitorId?: string;
165
177
  /** Optional explicit envelope fields. */
166
178
  eventId?: string;
167
179
  timestamp?: string | Date;
@@ -197,6 +209,8 @@ type TrackEvent = ({
197
209
  properties?: PurchaseCompletedProperties;
198
210
  } & BaseTrackEvent) | ({
199
211
  event: "user.identified";
212
+ } & BaseTrackEvent) | ({
213
+ event: "widget_render";
200
214
  } & BaseTrackEvent) | ({
201
215
  event: "price_shown";
202
216
  properties?: PriceShownProperties;
@@ -238,10 +252,9 @@ interface RevenuePricesComparedInput extends TrackingContext, PricesComparedProp
238
252
  interface RevenueOptionSelectedInput extends TrackingContext, OptionSelectedProperties {
239
253
  }
240
254
  /**
241
- * Input for `track.leadQualified()`. `source` is the lead's acquisition source
242
- * (the event property, e.g. "newsletter") on this helper it shadows the
243
- * envelope `source` from the tracking context. To set a custom envelope source
244
- * on a lead, use the generic `track({ event: "lead_qualified", … })`.
255
+ * Input for `track.leadQualified()` identity only (`externalId`, `email`,
256
+ * `name`) plus the shared tracking context. There is no acquisition-source
257
+ * property; the envelope `source` (the origin channel) is set automatically.
245
258
  */
246
259
  interface RevenueLeadQualifiedInput extends TrackingContext, LeadQualifiedProperties {
247
260
  }
@@ -265,13 +278,6 @@ interface RevenueTrackingApi {
265
278
  leadQualified: (input?: RevenueLeadQualifiedInput) => Promise<{
266
279
  eventId: string;
267
280
  }>;
268
- /**
269
- * @deprecated Renamed in 0.15.0. Use `track.leadQualified()` instead; this
270
- * alias emits a `lead_qualified` event and will be removed in 0.16.0.
271
- */
272
- lead: (input?: RevenueLeadQualifiedInput) => Promise<{
273
- eventId: string;
274
- }>;
275
281
  converted: (input: RevenueConvertedInput) => Promise<{
276
282
  eventId: string;
277
283
  }>;
@@ -3,6 +3,250 @@ import * as ai from 'ai';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import { ContentBlock } from '@modelcontextprotocol/sdk/types.js';
5
5
 
6
+ interface SearchResult {
7
+ source: string;
8
+ heading: string;
9
+ content: string;
10
+ score: number;
11
+ metadata?: Record<string, string>;
12
+ }
13
+ interface KbSearchTrace {
14
+ query: string;
15
+ resultCount: number;
16
+ results: Array<Pick<SearchResult, "source" | "heading" | "score">>;
17
+ }
18
+
19
+ /**
20
+ * Every event name in the typed taxonomy, as a runtime list. Single source of
21
+ * truth for {@link EventType} and for surfaces that need to recognize
22
+ * first-class names at runtime (the widget transport passes these through
23
+ * verbatim instead of namespacing them as custom widget events).
24
+ */
25
+ declare const EVENT_TYPES: readonly ["session.started", "page.viewed", "tool.called", "quote.requested", "quote.succeeded", "quote.failed", "link.clicked", "purchase.completed", "widget_render", "user.identified", "price_shown", "prices_compared", "option_selected", "lead_qualified", "converted"];
26
+ type EventType = (typeof EVENT_TYPES)[number];
27
+ /**
28
+ * Properties for `page.viewed` — emitted once when the chat widget initializes
29
+ * on a host page (the top of the funnel). Attributed to the anonymous
30
+ * `visitorId` (mapped to `externalUserId`), never to a session: a page view
31
+ * must not create a session, otherwise sessions would equal page views and the
32
+ * "landed → started a conversation" funnel collapses.
33
+ */
34
+ interface PageViewedProperties {
35
+ /** Full URL of the host page the widget loaded on. */
36
+ url?: string;
37
+ /** Referrer of the host page, if any. */
38
+ referrer?: string;
39
+ /** Embed mode the widget initialized in. */
40
+ mode?: "inline" | "floating";
41
+ /** Resolved device type from the visitor context. */
42
+ deviceType?: "mobile" | "tablet" | "desktop";
43
+ /** Primary browser language (BCP-47). */
44
+ language?: string;
45
+ /** IANA timezone of the visitor. */
46
+ timezone?: string;
47
+ }
48
+ interface ToolCalledProperties {
49
+ name?: string;
50
+ type?: "pricing" | "product_info" | "availability" | "support" | "other";
51
+ /** Retrieval traces for kb.search() calls made inside this tool handler. */
52
+ kbSearch?: KbSearchTrace[];
53
+ }
54
+ interface QuoteSucceededProperties {
55
+ amount?: number;
56
+ currency?: string;
57
+ }
58
+ interface LinkClickedProperties {
59
+ url?: string;
60
+ }
61
+ interface PurchaseCompletedProperties {
62
+ amount?: number;
63
+ currency?: string;
64
+ }
65
+ interface PriceShownProperties {
66
+ amount: number;
67
+ currency: string;
68
+ itemId?: string;
69
+ label?: string;
70
+ }
71
+ interface ComparedPriceOption {
72
+ id: string;
73
+ amount: number;
74
+ currency: string;
75
+ }
76
+ interface PricesComparedProperties {
77
+ options: ComparedPriceOption[];
78
+ }
79
+ interface OptionSelectedProperties {
80
+ id: string;
81
+ amount: number;
82
+ currency: string;
83
+ }
84
+ /**
85
+ * Properties for `lead_qualified` — your code declaring that a person met your
86
+ * qualification bar (finished the qualifying questions, requested a demo,
87
+ * matched your target profile). Sharing an email mid-conversation is
88
+ * `identify(userId, { email })`, not a qualified lead.
89
+ */
90
+ interface LeadQualifiedProperties {
91
+ /**
92
+ * Your own lead id (e.g. the record id your lead-gen API returns). The
93
+ * strongest dedup key and the stable reference back to your system.
94
+ */
95
+ externalId?: string;
96
+ /** The lead's email, if known. */
97
+ email?: string;
98
+ /** The lead's name, if known. */
99
+ name?: string;
100
+ }
101
+ interface ConvertedProperties {
102
+ amount: number;
103
+ currency: string;
104
+ /** When the conversion actually happened — for backdated off-platform sales. */
105
+ occurredAt?: string;
106
+ }
107
+ interface TrackingContext {
108
+ /**
109
+ * MCP request metadata passed through to the API.
110
+ *
111
+ * Location varies by MCP library:
112
+ * - `@vercel/mcp-handler`: `extra._meta`
113
+ * - `@modelcontextprotocol/sdk`: `request.params._meta`
114
+ */
115
+ meta?: Record<string, unknown>;
116
+ /** Legacy metadata field supported for backward compatibility. */
117
+ metadata?: Record<string, unknown>;
118
+ /** Optional explicit correlation fields. */
119
+ sessionId?: string;
120
+ traceId?: string;
121
+ requestId?: string;
122
+ correlationId?: string;
123
+ externalUserId?: string;
124
+ /**
125
+ * Anonymous visitor id (the analytics "device id"). Counts as identity on
126
+ * its own: the ingest API accepts `sessionId`, `externalUserId`, or
127
+ * `visitorId`. The chat widget uses it for pre-session events like
128
+ * `page.viewed`.
129
+ */
130
+ visitorId?: string;
131
+ /** Optional explicit envelope fields. */
132
+ eventId?: string;
133
+ timestamp?: string | Date;
134
+ source?: string;
135
+ }
136
+ /**
137
+ * Modern tracking shape (preferred).
138
+ */
139
+ interface BaseTrackEvent extends TrackingContext {
140
+ event: EventType;
141
+ properties?: Record<string, unknown>;
142
+ }
143
+ type TrackEvent = ({
144
+ event: "session.started";
145
+ } & BaseTrackEvent) | ({
146
+ event: "page.viewed";
147
+ properties?: PageViewedProperties;
148
+ } & BaseTrackEvent) | ({
149
+ event: "tool.called";
150
+ properties?: ToolCalledProperties;
151
+ } & BaseTrackEvent) | ({
152
+ event: "quote.requested";
153
+ } & BaseTrackEvent) | ({
154
+ event: "quote.succeeded";
155
+ properties?: QuoteSucceededProperties;
156
+ } & BaseTrackEvent) | ({
157
+ event: "quote.failed";
158
+ } & BaseTrackEvent) | ({
159
+ event: "link.clicked";
160
+ properties?: LinkClickedProperties;
161
+ } & BaseTrackEvent) | ({
162
+ event: "purchase.completed";
163
+ properties?: PurchaseCompletedProperties;
164
+ } & BaseTrackEvent) | ({
165
+ event: "user.identified";
166
+ } & BaseTrackEvent) | ({
167
+ event: "widget_render";
168
+ } & BaseTrackEvent) | ({
169
+ event: "price_shown";
170
+ properties?: PriceShownProperties;
171
+ } & BaseTrackEvent) | ({
172
+ event: "prices_compared";
173
+ properties?: PricesComparedProperties;
174
+ } & BaseTrackEvent) | ({
175
+ event: "option_selected";
176
+ properties?: OptionSelectedProperties;
177
+ } & BaseTrackEvent) | ({
178
+ event: "lead_qualified";
179
+ properties?: LeadQualifiedProperties;
180
+ } & BaseTrackEvent) | ({
181
+ event: "converted";
182
+ properties?: ConvertedProperties;
183
+ } & BaseTrackEvent);
184
+ /**
185
+ * Legacy tracking shape supported for existing integrations.
186
+ */
187
+ interface LegacyTrackEvent extends TrackingContext {
188
+ eventType: EventType;
189
+ properties?: Record<string, unknown>;
190
+ toolName?: string;
191
+ toolType?: ToolCalledProperties["type"];
192
+ quoteAmount?: number;
193
+ quoteCurrency?: string;
194
+ linkUrl?: string;
195
+ purchaseAmount?: number;
196
+ purchaseCurrency?: string;
197
+ }
198
+ /**
199
+ * Public track input accepted by `client.track()`.
200
+ */
201
+ type TrackInput = TrackEvent | LegacyTrackEvent;
202
+ interface RevenuePriceShownInput extends TrackingContext, PriceShownProperties {
203
+ }
204
+ interface RevenuePricesComparedInput extends TrackingContext, PricesComparedProperties {
205
+ }
206
+ interface RevenueOptionSelectedInput extends TrackingContext, OptionSelectedProperties {
207
+ }
208
+ /**
209
+ * Input for `track.leadQualified()` — identity only (`externalId`, `email`,
210
+ * `name`) plus the shared tracking context. There is no acquisition-source
211
+ * property; the envelope `source` (the origin channel) is set automatically.
212
+ */
213
+ interface RevenueLeadQualifiedInput extends TrackingContext, LeadQualifiedProperties {
214
+ }
215
+ interface RevenueConvertedInput extends TrackingContext, ConvertedProperties {
216
+ }
217
+ /**
218
+ * Revenue-oriented helpers, flat on `client.track.*` (e.g.
219
+ * `client.track.priceShown()`, `client.track.converted()`). Decoupled from
220
+ * product primitives — each maps to a typed first-class revenue event.
221
+ */
222
+ interface RevenueTrackingApi {
223
+ priceShown: (input: RevenuePriceShownInput) => Promise<{
224
+ eventId: string;
225
+ }>;
226
+ pricesCompared: (input: RevenuePricesComparedInput) => Promise<{
227
+ eventId: string;
228
+ }>;
229
+ optionSelected: (input: RevenueOptionSelectedInput) => Promise<{
230
+ eventId: string;
231
+ }>;
232
+ leadQualified: (input?: RevenueLeadQualifiedInput) => Promise<{
233
+ eventId: string;
234
+ }>;
235
+ converted: (input: RevenueConvertedInput) => Promise<{
236
+ eventId: string;
237
+ }>;
238
+ }
239
+ /**
240
+ * `client.track` — callable for generic events (`track(event)`), with the
241
+ * revenue helpers attached flat: `track.priceShown()`, `track.leadQualified()`,
242
+ * `track.converted()`, etc.
243
+ */
244
+ interface TrackFn extends RevenueTrackingApi {
245
+ (event: TrackInput): Promise<{
246
+ eventId: string;
247
+ }>;
248
+ }
249
+
6
250
  /**
7
251
  * Chat widget translation types.
8
252
  *
@@ -409,6 +653,21 @@ interface ChatHandle {
409
653
  messages: ai.UIMessage[];
410
654
  /** Session ID used for event correlation. Available after the first message. */
411
655
  sessionId: string | undefined;
656
+ /**
657
+ * Track a funnel event from the host page with the chat session attached
658
+ * automatically. Same surface as the server client: callable with a typed
659
+ * event, plus the flat revenue helpers (`track.converted({ ... })`, ...).
660
+ * Present on `WaniwaniChat` (hosted); absent on the bare `ChatEmbed`
661
+ * primitive, which has no Waniwani credential to send events with.
662
+ */
663
+ track?: TrackFn;
664
+ /**
665
+ * Tie the visitor to a stable user id (emits `user.identified`).
666
+ * Present on `WaniwaniChat` only, like `track`.
667
+ */
668
+ identify?: (userId: string, traits?: Record<string, unknown>) => Promise<{
669
+ eventId: string;
670
+ }>;
412
671
  }
413
672
 
414
673
  /** @deprecated Use `WaniwaniChat` (hosted, React) or the `<script>` embed for new code. `ChatCard` is preserved for back-compat only and lives under `@waniwani/sdk/legacy`. */