@waniwani/sdk 0.15.2 → 0.17.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
@@ -160,6 +167,13 @@ interface TrackingContext {
160
167
  requestId?: string;
161
168
  correlationId?: string;
162
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;
163
177
  /** Optional explicit envelope fields. */
164
178
  eventId?: string;
165
179
  timestamp?: string | Date;
@@ -195,6 +209,8 @@ type TrackEvent = ({
195
209
  properties?: PurchaseCompletedProperties;
196
210
  } & BaseTrackEvent) | ({
197
211
  event: "user.identified";
212
+ } & BaseTrackEvent) | ({
213
+ event: "widget_render";
198
214
  } & BaseTrackEvent) | ({
199
215
  event: "price_shown";
200
216
  properties?: PriceShownProperties;
@@ -262,13 +278,6 @@ interface RevenueTrackingApi {
262
278
  leadQualified: (input?: RevenueLeadQualifiedInput) => Promise<{
263
279
  eventId: string;
264
280
  }>;
265
- /**
266
- * @deprecated Renamed in 0.15.0. Use `track.leadQualified()` instead; this
267
- * alias emits a `lead_qualified` event and will be removed in 0.16.0.
268
- */
269
- lead: (input?: RevenueLeadQualifiedInput) => Promise<{
270
- eventId: string;
271
- }>;
272
281
  converted: (input: RevenueConvertedInput) => Promise<{
273
282
  eventId: string;
274
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
  *
@@ -113,6 +357,13 @@ interface ChatAppearance {
113
357
  theme?: ThemePreset;
114
358
  /** Per-property overrides applied on top of the preset. */
115
359
  variables?: ChatTheme;
360
+ /**
361
+ * Render assistant messages inside a filled bubble (background + padding +
362
+ * radius), styled by `variables.assistantBubbleColor` /
363
+ * `assistantBubbleTextColor`. Defaults to `false` — assistant messages
364
+ * render as plain text. Opt in for a "both sides bubbled" chat style.
365
+ */
366
+ assistantBubble?: boolean;
116
367
  }
117
368
  /**
118
369
  * Tool-call activity rendering mode. Steps are grouped into one collapsible
@@ -162,6 +413,20 @@ interface ChatTheme {
162
413
  statusColor?: string;
163
414
  /** Tool call JSON section background. Defaults to light gray / #262626 in dark. */
164
415
  toolCardColor?: string;
416
+ /** Text color inside the user message bubble. Falls back to `primaryForeground`. */
417
+ userBubbleTextColor?: string;
418
+ /** Text color inside the assistant message bubble (only visible when `appearance.assistantBubble` is enabled). Falls back to `textColor`. */
419
+ assistantBubbleTextColor?: string;
420
+ /** Horizontal padding inside message bubbles (px). Defaults to 16. */
421
+ messagePaddingX?: number;
422
+ /** Vertical padding inside message bubbles (px). Defaults to 12. */
423
+ messagePaddingY?: number;
424
+ /** Max width of a message bubble as a CSS length/percentage. Defaults to `"80%"`. */
425
+ messageMaxWidth?: string;
426
+ /** Base font size for message text (px). When unset, messages use the CSS default of `1rem` (16px at the standard root font size). */
427
+ fontSize?: number;
428
+ /** Base line height for message text (unitless string, e.g. `"1.5"`). Defaults to `"1.5"`. */
429
+ lineHeight?: string;
165
430
  }
166
431
  interface WelcomeConfig {
167
432
  /** Icon displayed above the title. Accepts any React node (e.g. an SVG or img). */
@@ -185,6 +450,27 @@ interface SuggestionsConfig {
185
450
  */
186
451
  dynamic?: boolean;
187
452
  }
453
+ /**
454
+ * Per-slot class name overrides for the chat widget. Each string is appended
455
+ * to the slot's own classes (merged with `tailwind-merge`, `ww` prefix). Use
456
+ * with your own (prefixed or plain) CSS to restyle any element. In the React
457
+ * path these reach into internals directly; in the `<script>` embed, prefer
458
+ * the stable `.ww-*` semantic classes with a `data-css` stylesheet.
459
+ */
460
+ interface ChatClassNames {
461
+ /** Root chat container. */
462
+ root?: string;
463
+ /** Sticky header bar. */
464
+ header?: string;
465
+ /** Every message wrapper (both roles). */
466
+ message?: string;
467
+ /** The user message bubble content. */
468
+ userBubble?: string;
469
+ /** The assistant message bubble content. */
470
+ assistantBubble?: string;
471
+ /** The input bar container. */
472
+ input?: string;
473
+ }
188
474
  interface ChatBaseProps {
189
475
  /** Waniwani project API key */
190
476
  apiKey?: string;
@@ -206,6 +492,8 @@ interface ChatBaseProps {
206
492
  * See `ChatAppearance` for the shape.
207
493
  */
208
494
  appearance?: ChatAppearance;
495
+ /** Per-slot class name overrides. See {@link ChatClassNames}. */
496
+ classNames?: ChatClassNames;
209
497
  /** Additional headers to send with chat API requests */
210
498
  headers?: Record<string, string>;
211
499
  /** Additional body fields to send with each chat request */
@@ -409,6 +697,21 @@ interface ChatHandle {
409
697
  messages: ai.UIMessage[];
410
698
  /** Session ID used for event correlation. Available after the first message. */
411
699
  sessionId: string | undefined;
700
+ /**
701
+ * Track a funnel event from the host page with the chat session attached
702
+ * automatically. Same surface as the server client: callable with a typed
703
+ * event, plus the flat revenue helpers (`track.converted({ ... })`, ...).
704
+ * Present on `WaniwaniChat` (hosted); absent on the bare `ChatEmbed`
705
+ * primitive, which has no Waniwani credential to send events with.
706
+ */
707
+ track?: TrackFn;
708
+ /**
709
+ * Tie the visitor to a stable user id (emits `user.identified`).
710
+ * Present on `WaniwaniChat` only, like `track`.
711
+ */
712
+ identify?: (userId: string, traits?: Record<string, unknown>) => Promise<{
713
+ eventId: string;
714
+ }>;
412
715
  }
413
716
 
414
717
  /** @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`. */
@@ -567,6 +870,8 @@ interface WaniwaniChatOverrides {
567
870
  * ```
568
871
  */
569
872
  appearance?: ChatAppearance;
873
+ /** Per-slot class name overrides. See `ChatClassNames`. */
874
+ classNames?: ChatClassNames;
570
875
  /** Chat API URL. Defaults to `https://app.waniwani.ai/api/mcp/chat`. */
571
876
  api?: string;
572
877
  /** Override the MCP server URL (rarely needed). */