@mordn/chat-widget 0.6.2 → 0.7.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/dist/index.d.mts CHANGED
@@ -1,9 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import { ReactNode, HTMLAttributes } from 'react';
2
+ import * as React$1 from 'react';
3
+ import { ReactNode, HTMLAttributes, ComponentProps } from 'react';
4
4
  import * as class_variance_authority_types from 'class-variance-authority/types';
5
5
  import { VariantProps } from 'class-variance-authority';
6
6
  import * as DialogPrimitive from '@radix-ui/react-dialog';
7
+ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
8
+ import { ToolUIPart } from 'ai';
7
9
 
8
10
  /**
9
11
  * ChatWidget Configuration Types
@@ -102,6 +104,46 @@ interface ChatWidgetConfig {
102
104
  * character.
103
105
  */
104
106
  inputPlugins?: InputPlugin[];
107
+ /**
108
+ * Per-tool custom renderers. When a tool part appears in a message
109
+ * (either a static `tool-<name>` part or a `dynamic-tool` part with
110
+ * `toolName: <name>`), the widget looks up the renderer keyed by tool
111
+ * name and uses it instead of the default JSON-dump tool block.
112
+ *
113
+ * Renderer receives the full tool part and must return a React node.
114
+ * It owns its visual presentation entirely — table, cards, chart,
115
+ * inline summary, whatever fits the data. Return null to fall back
116
+ * to the default rendering (useful for partial-state tool calls
117
+ * where you only want custom rendering once results arrive).
118
+ *
119
+ * The widget knows nothing about specific tools; consumers are
120
+ * responsible for the renderer mapping. This keeps the widget
121
+ * domain-agnostic while letting host apps make tool results feel
122
+ * native.
123
+ */
124
+ toolRenderers?: Record<string, ToolRenderer>;
125
+ }
126
+ /**
127
+ * Render function for a tool UI part. Receives the entire part so the
128
+ * renderer can branch on `state` (input-streaming / output-available /
129
+ * output-error) and on the input/output shapes.
130
+ */
131
+ type ToolRenderer = (part: ToolPartLike) => ReactNode | null;
132
+ /**
133
+ * Loose shape of the tool parts the renderer will receive — covers
134
+ * both static `ToolUIPart<TOOLS>` and the dynamic-tool variant. Kept
135
+ * loose so consumers don't have to import internal AI SDK types.
136
+ */
137
+ interface ToolPartLike {
138
+ /** Either `tool-<name>` or `'dynamic-tool'`. */
139
+ type: string;
140
+ /** Always present on dynamic-tool parts; sometimes absent on static. */
141
+ toolName?: string;
142
+ toolCallId: string;
143
+ state: 'input-streaming' | 'input-available' | 'output-available' | 'output-error';
144
+ input?: unknown;
145
+ output?: unknown;
146
+ errorText?: string;
105
147
  }
106
148
  /**
107
149
  * Item returned by an InputPlugin's fetch function. Renders as one row
@@ -197,9 +239,27 @@ interface ThemeConfig {
197
239
  }
198
240
  interface FeatureConfig {
199
241
  /**
200
- * Enable file uploads
242
+ * Enable file uploads. When true, the input toolbar shows a paperclip
243
+ * button and accepts files matching `fileUploadAccept`.
201
244
  */
202
245
  fileUpload?: boolean;
246
+ /**
247
+ * Comma-separated `accept` filter passed to the file picker when
248
+ * `fileUpload` is true. Mirrors the HTML input[type=file] `accept`
249
+ * syntax (e.g. `"image/*,application/pdf,.csv"`). Defaults to
250
+ * `"image/*"` for backwards compatibility — consumers serving more
251
+ * file types should set this to whatever their server / model
252
+ * actually accepts.
253
+ */
254
+ fileUploadAccept?: string;
255
+ /**
256
+ * Per-file size cap in bytes. The file picker / drag-and-drop
257
+ * surface rejects files above this size before any network call,
258
+ * showing the consumer's onError hook. Should mirror whatever the
259
+ * upload endpoint enforces server-side. When unset, no client-side
260
+ * size check is applied.
261
+ */
262
+ fileUploadMaxBytes?: number;
203
263
  /**
204
264
  * Enable web search
205
265
  */
@@ -288,7 +348,7 @@ interface ChatWidgetProps extends ChatWidgetConfig {
288
348
  */
289
349
  widgetId?: string;
290
350
  }
291
- declare function ChatWidget({ userId, conversationId, initialMessages, className, model, systemPrompt, temperature, theme, features, display, starterPrompts, onClose, headerActions, open, onOpenChange, inputPlugins, }: ChatWidgetProps): react_jsx_runtime.JSX.Element;
351
+ declare function ChatWidget({ userId, conversationId, initialMessages, className, model, systemPrompt, temperature, theme, features, display, starterPrompts, onClose, headerActions, open, onOpenChange, inputPlugins, toolRenderers, }: ChatWidgetProps): react_jsx_runtime.JSX.Element;
292
352
 
293
353
  interface ChatTheme {
294
354
  lightPrimary: string;
@@ -350,21 +410,21 @@ declare const buttonVariants: (props?: ({
350
410
  variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
351
411
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
352
412
  } & class_variance_authority_types.ClassProp) | undefined) => string;
353
- declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
413
+ declare function Button({ className, variant, size, asChild, ...props }: React$1.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
354
414
  asChild?: boolean;
355
415
  }): react_jsx_runtime.JSX.Element;
356
416
 
357
- interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
417
+ interface InputProps extends React$1.InputHTMLAttributes<HTMLInputElement> {
358
418
  }
359
- declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
419
+ declare const Input: React$1.ForwardRefExoticComponent<InputProps & React$1.RefAttributes<HTMLInputElement>>;
360
420
 
361
- declare function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>): react_jsx_runtime.JSX.Element;
362
- declare function DialogContent({ className, children, showCloseButton, ...props }: React.ComponentProps<typeof DialogPrimitive.Content> & {
421
+ declare function Dialog({ ...props }: React$1.ComponentProps<typeof DialogPrimitive.Root>): react_jsx_runtime.JSX.Element;
422
+ declare function DialogContent({ className, children, showCloseButton, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Content> & {
363
423
  showCloseButton?: boolean;
364
424
  }): react_jsx_runtime.JSX.Element;
365
- declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
366
- declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>): react_jsx_runtime.JSX.Element;
367
- declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>): react_jsx_runtime.JSX.Element;
425
+ declare function DialogHeader({ className, ...props }: React$1.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
426
+ declare function DialogTitle({ className, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Title>): react_jsx_runtime.JSX.Element;
427
+ declare function DialogDescription({ className, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Description>): react_jsx_runtime.JSX.Element;
368
428
 
369
429
  type StarterMessagesProps = Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> & {
370
430
  prompts: StarterPrompt[];
@@ -376,4 +436,36 @@ type StarterMessageItemProps = HTMLAttributes<HTMLButtonElement> & {
376
436
  };
377
437
  declare function StarterMessageItem({ className, prompt, onClick, ...props }: StarterMessageItemProps): react_jsx_runtime.JSX.Element;
378
438
 
379
- export { Button, ChatStorageProvider, type ChatTheme, ChatWidget, type ChatWidgetConfig, type ChatWidgetProps, type ChatWidgetSize, type ConversationStarter, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, type DisplayConfig, type FeatureConfig, Input, type InputPlugin, type InputPluginItem, StarterMessageItem, StarterMessages, type StarterPrompt, type ThemeConfig, type ThemeMode, ChatWidget as default, fontOptions, useChatStorageKey, useChatTheme };
439
+ declare function Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>): react_jsx_runtime.JSX.Element;
440
+ declare function CollapsibleContent({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>): react_jsx_runtime.JSX.Element;
441
+
442
+ type ToolProps = ComponentProps<typeof Collapsible>;
443
+ declare const Tool: ({ className, ...props }: ToolProps) => react_jsx_runtime.JSX.Element;
444
+ type ToolHeaderProps = {
445
+ title?: string;
446
+ type: ToolUIPart["type"] | "dynamic-tool";
447
+ /**
448
+ * Set when the part is a `dynamic-tool` UIPart (MCP / `dynamicTool()`).
449
+ * For these the `type` is always `"dynamic-tool"`, so the actual tool
450
+ * identity lives in `toolName`. When provided, it wins over the parsed
451
+ * type fragment so the header shows e.g. `get_financials` instead of
452
+ * the generic `tool`.
453
+ */
454
+ toolName?: string;
455
+ state: ToolUIPart["state"];
456
+ className?: string;
457
+ };
458
+ declare const ToolHeader: ({ className, title, type, toolName, state, ...props }: ToolHeaderProps) => react_jsx_runtime.JSX.Element;
459
+ type ToolContentProps = ComponentProps<typeof CollapsibleContent>;
460
+ declare const ToolContent: ({ className, ...props }: ToolContentProps) => react_jsx_runtime.JSX.Element;
461
+ type ToolInputProps = ComponentProps<"div"> & {
462
+ input: ToolUIPart["input"];
463
+ };
464
+ declare const ToolInput: ({ className, input, ...props }: ToolInputProps) => react_jsx_runtime.JSX.Element;
465
+ type ToolOutputProps = ComponentProps<"div"> & {
466
+ output: ToolUIPart["output"];
467
+ errorText: ToolUIPart["errorText"];
468
+ };
469
+ declare const ToolOutput: ({ className, output, errorText, ...props }: ToolOutputProps) => react_jsx_runtime.JSX.Element | null;
470
+
471
+ export { Button, ChatStorageProvider, type ChatTheme, ChatWidget, type ChatWidgetConfig, type ChatWidgetProps, type ChatWidgetSize, type ConversationStarter, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, type DisplayConfig, type FeatureConfig, Input, type InputPlugin, type InputPluginItem, StarterMessageItem, StarterMessages, type StarterPrompt, type ThemeConfig, type ThemeMode, Tool, ToolContent, ToolHeader, ToolInput, ToolOutput, type ToolPartLike, type ToolRenderer, ChatWidget as default, fontOptions, useChatStorageKey, useChatTheme };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import { ReactNode, HTMLAttributes } from 'react';
2
+ import * as React$1 from 'react';
3
+ import { ReactNode, HTMLAttributes, ComponentProps } from 'react';
4
4
  import * as class_variance_authority_types from 'class-variance-authority/types';
5
5
  import { VariantProps } from 'class-variance-authority';
6
6
  import * as DialogPrimitive from '@radix-ui/react-dialog';
7
+ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
8
+ import { ToolUIPart } from 'ai';
7
9
 
8
10
  /**
9
11
  * ChatWidget Configuration Types
@@ -102,6 +104,46 @@ interface ChatWidgetConfig {
102
104
  * character.
103
105
  */
104
106
  inputPlugins?: InputPlugin[];
107
+ /**
108
+ * Per-tool custom renderers. When a tool part appears in a message
109
+ * (either a static `tool-<name>` part or a `dynamic-tool` part with
110
+ * `toolName: <name>`), the widget looks up the renderer keyed by tool
111
+ * name and uses it instead of the default JSON-dump tool block.
112
+ *
113
+ * Renderer receives the full tool part and must return a React node.
114
+ * It owns its visual presentation entirely — table, cards, chart,
115
+ * inline summary, whatever fits the data. Return null to fall back
116
+ * to the default rendering (useful for partial-state tool calls
117
+ * where you only want custom rendering once results arrive).
118
+ *
119
+ * The widget knows nothing about specific tools; consumers are
120
+ * responsible for the renderer mapping. This keeps the widget
121
+ * domain-agnostic while letting host apps make tool results feel
122
+ * native.
123
+ */
124
+ toolRenderers?: Record<string, ToolRenderer>;
125
+ }
126
+ /**
127
+ * Render function for a tool UI part. Receives the entire part so the
128
+ * renderer can branch on `state` (input-streaming / output-available /
129
+ * output-error) and on the input/output shapes.
130
+ */
131
+ type ToolRenderer = (part: ToolPartLike) => ReactNode | null;
132
+ /**
133
+ * Loose shape of the tool parts the renderer will receive — covers
134
+ * both static `ToolUIPart<TOOLS>` and the dynamic-tool variant. Kept
135
+ * loose so consumers don't have to import internal AI SDK types.
136
+ */
137
+ interface ToolPartLike {
138
+ /** Either `tool-<name>` or `'dynamic-tool'`. */
139
+ type: string;
140
+ /** Always present on dynamic-tool parts; sometimes absent on static. */
141
+ toolName?: string;
142
+ toolCallId: string;
143
+ state: 'input-streaming' | 'input-available' | 'output-available' | 'output-error';
144
+ input?: unknown;
145
+ output?: unknown;
146
+ errorText?: string;
105
147
  }
106
148
  /**
107
149
  * Item returned by an InputPlugin's fetch function. Renders as one row
@@ -197,9 +239,27 @@ interface ThemeConfig {
197
239
  }
198
240
  interface FeatureConfig {
199
241
  /**
200
- * Enable file uploads
242
+ * Enable file uploads. When true, the input toolbar shows a paperclip
243
+ * button and accepts files matching `fileUploadAccept`.
201
244
  */
202
245
  fileUpload?: boolean;
246
+ /**
247
+ * Comma-separated `accept` filter passed to the file picker when
248
+ * `fileUpload` is true. Mirrors the HTML input[type=file] `accept`
249
+ * syntax (e.g. `"image/*,application/pdf,.csv"`). Defaults to
250
+ * `"image/*"` for backwards compatibility — consumers serving more
251
+ * file types should set this to whatever their server / model
252
+ * actually accepts.
253
+ */
254
+ fileUploadAccept?: string;
255
+ /**
256
+ * Per-file size cap in bytes. The file picker / drag-and-drop
257
+ * surface rejects files above this size before any network call,
258
+ * showing the consumer's onError hook. Should mirror whatever the
259
+ * upload endpoint enforces server-side. When unset, no client-side
260
+ * size check is applied.
261
+ */
262
+ fileUploadMaxBytes?: number;
203
263
  /**
204
264
  * Enable web search
205
265
  */
@@ -288,7 +348,7 @@ interface ChatWidgetProps extends ChatWidgetConfig {
288
348
  */
289
349
  widgetId?: string;
290
350
  }
291
- declare function ChatWidget({ userId, conversationId, initialMessages, className, model, systemPrompt, temperature, theme, features, display, starterPrompts, onClose, headerActions, open, onOpenChange, inputPlugins, }: ChatWidgetProps): react_jsx_runtime.JSX.Element;
351
+ declare function ChatWidget({ userId, conversationId, initialMessages, className, model, systemPrompt, temperature, theme, features, display, starterPrompts, onClose, headerActions, open, onOpenChange, inputPlugins, toolRenderers, }: ChatWidgetProps): react_jsx_runtime.JSX.Element;
292
352
 
293
353
  interface ChatTheme {
294
354
  lightPrimary: string;
@@ -350,21 +410,21 @@ declare const buttonVariants: (props?: ({
350
410
  variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
351
411
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
352
412
  } & class_variance_authority_types.ClassProp) | undefined) => string;
353
- declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
413
+ declare function Button({ className, variant, size, asChild, ...props }: React$1.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
354
414
  asChild?: boolean;
355
415
  }): react_jsx_runtime.JSX.Element;
356
416
 
357
- interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
417
+ interface InputProps extends React$1.InputHTMLAttributes<HTMLInputElement> {
358
418
  }
359
- declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
419
+ declare const Input: React$1.ForwardRefExoticComponent<InputProps & React$1.RefAttributes<HTMLInputElement>>;
360
420
 
361
- declare function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>): react_jsx_runtime.JSX.Element;
362
- declare function DialogContent({ className, children, showCloseButton, ...props }: React.ComponentProps<typeof DialogPrimitive.Content> & {
421
+ declare function Dialog({ ...props }: React$1.ComponentProps<typeof DialogPrimitive.Root>): react_jsx_runtime.JSX.Element;
422
+ declare function DialogContent({ className, children, showCloseButton, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Content> & {
363
423
  showCloseButton?: boolean;
364
424
  }): react_jsx_runtime.JSX.Element;
365
- declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
366
- declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>): react_jsx_runtime.JSX.Element;
367
- declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>): react_jsx_runtime.JSX.Element;
425
+ declare function DialogHeader({ className, ...props }: React$1.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
426
+ declare function DialogTitle({ className, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Title>): react_jsx_runtime.JSX.Element;
427
+ declare function DialogDescription({ className, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Description>): react_jsx_runtime.JSX.Element;
368
428
 
369
429
  type StarterMessagesProps = Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> & {
370
430
  prompts: StarterPrompt[];
@@ -376,4 +436,36 @@ type StarterMessageItemProps = HTMLAttributes<HTMLButtonElement> & {
376
436
  };
377
437
  declare function StarterMessageItem({ className, prompt, onClick, ...props }: StarterMessageItemProps): react_jsx_runtime.JSX.Element;
378
438
 
379
- export { Button, ChatStorageProvider, type ChatTheme, ChatWidget, type ChatWidgetConfig, type ChatWidgetProps, type ChatWidgetSize, type ConversationStarter, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, type DisplayConfig, type FeatureConfig, Input, type InputPlugin, type InputPluginItem, StarterMessageItem, StarterMessages, type StarterPrompt, type ThemeConfig, type ThemeMode, ChatWidget as default, fontOptions, useChatStorageKey, useChatTheme };
439
+ declare function Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>): react_jsx_runtime.JSX.Element;
440
+ declare function CollapsibleContent({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>): react_jsx_runtime.JSX.Element;
441
+
442
+ type ToolProps = ComponentProps<typeof Collapsible>;
443
+ declare const Tool: ({ className, ...props }: ToolProps) => react_jsx_runtime.JSX.Element;
444
+ type ToolHeaderProps = {
445
+ title?: string;
446
+ type: ToolUIPart["type"] | "dynamic-tool";
447
+ /**
448
+ * Set when the part is a `dynamic-tool` UIPart (MCP / `dynamicTool()`).
449
+ * For these the `type` is always `"dynamic-tool"`, so the actual tool
450
+ * identity lives in `toolName`. When provided, it wins over the parsed
451
+ * type fragment so the header shows e.g. `get_financials` instead of
452
+ * the generic `tool`.
453
+ */
454
+ toolName?: string;
455
+ state: ToolUIPart["state"];
456
+ className?: string;
457
+ };
458
+ declare const ToolHeader: ({ className, title, type, toolName, state, ...props }: ToolHeaderProps) => react_jsx_runtime.JSX.Element;
459
+ type ToolContentProps = ComponentProps<typeof CollapsibleContent>;
460
+ declare const ToolContent: ({ className, ...props }: ToolContentProps) => react_jsx_runtime.JSX.Element;
461
+ type ToolInputProps = ComponentProps<"div"> & {
462
+ input: ToolUIPart["input"];
463
+ };
464
+ declare const ToolInput: ({ className, input, ...props }: ToolInputProps) => react_jsx_runtime.JSX.Element;
465
+ type ToolOutputProps = ComponentProps<"div"> & {
466
+ output: ToolUIPart["output"];
467
+ errorText: ToolUIPart["errorText"];
468
+ };
469
+ declare const ToolOutput: ({ className, output, errorText, ...props }: ToolOutputProps) => react_jsx_runtime.JSX.Element | null;
470
+
471
+ export { Button, ChatStorageProvider, type ChatTheme, ChatWidget, type ChatWidgetConfig, type ChatWidgetProps, type ChatWidgetSize, type ConversationStarter, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, type DisplayConfig, type FeatureConfig, Input, type InputPlugin, type InputPluginItem, StarterMessageItem, StarterMessages, type StarterPrompt, type ThemeConfig, type ThemeMode, Tool, ToolContent, ToolHeader, ToolInput, ToolOutput, type ToolPartLike, type ToolRenderer, ChatWidget as default, fontOptions, useChatStorageKey, useChatTheme };