@miiflow/assistant-ui 0.5.2 → 0.9.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.
Files changed (42) hide show
  1. package/dist/{WelcomeScreen-D32Tsu6G.d.ts → WelcomeScreen-CVxniqqK.d.ts} +39 -9
  2. package/dist/{avatar-CAmTN1L7.d.ts → avatar-DnLePg72.d.ts} +2 -2
  3. package/dist/branding-NieTEGQf.d.ts +32 -0
  4. package/dist/chunk-ERJKVQQT.js +132 -0
  5. package/dist/chunk-ERJKVQQT.js.map +1 -0
  6. package/dist/chunk-IUCKTDTZ.js +2 -0
  7. package/dist/chunk-IUCKTDTZ.js.map +1 -0
  8. package/dist/chunk-NG4HKXYB.js +2 -0
  9. package/dist/chunk-NG4HKXYB.js.map +1 -0
  10. package/dist/chunk-NKLA5PPB.js +2 -0
  11. package/dist/chunk-NKLA5PPB.js.map +1 -0
  12. package/dist/chunk-QECTWT2H.js +2 -0
  13. package/dist/chunk-QECTWT2H.js.map +1 -0
  14. package/dist/client/index.d.ts +68 -4
  15. package/dist/client/index.js +7 -5
  16. package/dist/client/index.js.map +1 -1
  17. package/dist/composer/index.d.ts +180 -0
  18. package/dist/composer/index.js +2 -0
  19. package/dist/composer/index.js.map +1 -0
  20. package/dist/context/index.d.ts +16 -3
  21. package/dist/context/index.js +1 -1
  22. package/dist/hooks/index.d.ts +2 -2
  23. package/dist/hooks/index.js +1 -1
  24. package/dist/index.d.ts +18 -6
  25. package/dist/index.js +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/{message-D3D59U_Q.d.ts → message-D2ElX5k7.d.ts} +5 -4
  28. package/dist/primitives/index.d.ts +3 -3
  29. package/dist/{streaming-Q8hp5ev4.d.ts → streaming-B_u_jno6.d.ts} +77 -124
  30. package/dist/styled/index.d.ts +246 -73
  31. package/dist/styled/index.js +1 -1
  32. package/dist/styles-no-preflight.css +1 -1
  33. package/dist/styles.css +1 -1
  34. package/dist/types-DeHbndy0.d.ts +48 -0
  35. package/package.json +20 -3
  36. package/dist/branding-SzYU4ncD.d.ts +0 -18
  37. package/dist/chunk-NSTK5EUQ.js +0 -2
  38. package/dist/chunk-NSTK5EUQ.js.map +0 -1
  39. package/dist/chunk-OCKHJ4WO.js +0 -2
  40. package/dist/chunk-OCKHJ4WO.js.map +0 -1
  41. package/dist/chunk-VDFIXLNO.js +0 -20
  42. package/dist/chunk-VDFIXLNO.js.map +0 -1
@@ -0,0 +1,180 @@
1
+ import { c as CommandProvider, C as ChatComposerCommand, a as ChatComposerSubmitPayload } from '../types-DeHbndy0.js';
2
+ export { b as ChatComposerToken } from '../types-DeHbndy0.js';
3
+ import { DecoratorNode, NodeKey, Spread, SerializedLexicalNode, DOMExportOutput, DOMConversionMap, LexicalNode } from 'lexical';
4
+ import * as react from 'react';
5
+ import { ReactNode } from 'react';
6
+ import * as react_jsx_runtime from 'react/jsx-runtime';
7
+
8
+ type SerializedCommandTokenNode = Spread<{
9
+ commandId: string;
10
+ commandKind: string;
11
+ commandLabel: string;
12
+ /** Trigger character that produced the chip (e.g. "/" or "@"). Optional in
13
+ * v1 payloads — defaulted to "/" on import for backwards compatibility. */
14
+ commandPrefix?: string;
15
+ type: "command-token";
16
+ version: 1 | 2;
17
+ }, SerializedLexicalNode>;
18
+ declare class CommandTokenNode extends DecoratorNode<ReactNode> {
19
+ __id: string;
20
+ __kind: string;
21
+ __label: string;
22
+ __prefix: string;
23
+ constructor(id: string, kind: string, label: string, prefix?: string, key?: NodeKey);
24
+ static getType(): string;
25
+ static clone(node: CommandTokenNode): CommandTokenNode;
26
+ static importJSON(serialized: SerializedCommandTokenNode): CommandTokenNode;
27
+ exportJSON(): SerializedCommandTokenNode;
28
+ getCommandId(): string;
29
+ getCommandKind(): string;
30
+ getCommandLabel(): string;
31
+ getCommandPrefix(): string;
32
+ /** Wire format. Backend parses `<prefix><id>:<kind>` from the message body. */
33
+ getEncodedText(): string;
34
+ createDOM(): HTMLElement;
35
+ updateDOM(): false;
36
+ exportDOM(): DOMExportOutput;
37
+ static importDOM(): DOMConversionMap | null;
38
+ decorate(): ReactNode;
39
+ isInline(): boolean;
40
+ isKeyboardSelectable(): boolean;
41
+ /** Plain-text projection (clipboard, root.getTextContent, etc.). */
42
+ getTextContent(): string;
43
+ }
44
+ declare function $createCommandTokenNode(id: string, kind: string, label: string, prefix?: string): CommandTokenNode;
45
+ declare function $isCommandTokenNode(node: LexicalNode | null | undefined): node is CommandTokenNode;
46
+ /**
47
+ * Matches `<prefix><id>:<kind>` substrings emitted by `CommandTokenNode.getEncodedText()`,
48
+ * where `<prefix>` is `/` (skill / mode chips) or `@` (ad-account chips).
49
+ *
50
+ * Bounded by start-of-string, whitespace, or an opening bracket on the left,
51
+ * and end-of-string, whitespace, or punctuation on the right — so it doesn't
52
+ * fire on URLs like `https://example.com/path:foo` or emails like
53
+ * `user@host.com:port`.
54
+ *
55
+ * The id capture allows spaces (skill names may have them); the kind capture
56
+ * allows word chars and hyphens (e.g. `ad-account`).
57
+ */
58
+ declare const COMMAND_TOKEN_REGEX: RegExp;
59
+ interface InlineCommandTokenMatch {
60
+ id: string;
61
+ kind: string;
62
+ /** Trigger character that introduced the chip (`/` or `@`). */
63
+ prefix: string;
64
+ /** The full matched substring including the leading prefix (no leading boundary). */
65
+ raw: string;
66
+ /** Index in the original string where the leading prefix sits. */
67
+ index: number;
68
+ /** End index (exclusive) of the matched token. */
69
+ endIndex: number;
70
+ }
71
+ /**
72
+ * Find all `<prefix><id>:<kind>` tokens in a plain-text string.
73
+ *
74
+ * Returns matches in document order. Use this when rendering message
75
+ * history to replace token substrings with a visual chip.
76
+ */
77
+ declare function findInlineCommandTokens(text: string): InlineCommandTokenMatch[];
78
+
79
+ interface CommandTokenPluginProps {
80
+ /** The data source for the typeahead. When null, the plugin is inert. */
81
+ commandProvider?: CommandProvider | null;
82
+ /**
83
+ * Optional override for the typeahead UI. When supplied, replaces the
84
+ * default Tailwind popover (use this to render an MUI/host-themed menu).
85
+ */
86
+ menuRenderer?: (params: {
87
+ anchorElement: HTMLElement | null;
88
+ options: ChatComposerCommand[];
89
+ selectedIndex: number;
90
+ setSelectedIndex: (index: number) => void;
91
+ selectOption: (option: ChatComposerCommand) => void;
92
+ closeMenu: () => void;
93
+ }) => React.ReactNode;
94
+ /**
95
+ * Notified whenever the typeahead menu opens or closes. Use this to gate
96
+ * keyboard handlers (e.g. don't submit on Enter while the menu is open).
97
+ */
98
+ onMenuStateChange?: (isOpen: boolean) => void;
99
+ }
100
+ declare function CommandTokenPlugin({ commandProvider, menuRenderer, onMenuStateChange, }: CommandTokenPluginProps): React.JSX.Element | null;
101
+
102
+ /**
103
+ * Single source of truth for slash-command token visuals.
104
+ *
105
+ * Used in three places:
106
+ * - Typeahead popover row (variant="row")
107
+ * - Inline chip in the editor (variant="chip", inside CommandTokenNode.decorate)
108
+ * - Inline chip in message history (variant="chip", inside MarkdownContent)
109
+ *
110
+ * Renders a kind tag + label so the user gets the same visual identity at
111
+ * every step: pick → type → send → re-read. Adapts to the surrounding text
112
+ * color via `currentColor` so it survives light bubbles, dark bubbles, and
113
+ * any branded chat surface without bespoke palettes.
114
+ */
115
+ interface CommandTokenViewProps {
116
+ /** Slug-style id (wire format `/<id>:<kind>`). */
117
+ id: string;
118
+ /** Token category, e.g. "skill", "mode". Rendered as the leading tag. */
119
+ kind: string;
120
+ /** Display name; falls back to `id` if not provided. */
121
+ label?: string;
122
+ /** Optional secondary line; only rendered for variant="row". */
123
+ description?: string;
124
+ /** Optional leading icon (slotted before the label, after the tag). */
125
+ icon?: ReactNode;
126
+ /** Optional override for the leading tag (where `kind` renders by default).
127
+ * When set, replaces the uppercase kind pill — e.g. swap "AD-ACCOUNT" for
128
+ * the platform logo. */
129
+ tag?: ReactNode;
130
+ /** Compact inline pill ("chip") vs. full popover row ("row"). */
131
+ variant?: "chip" | "row";
132
+ /** When true, applies the row's "selected" styling. */
133
+ selected?: boolean;
134
+ /** Optional click handler (popover row uses it; chip doesn't by default). */
135
+ onMouseEnter?: () => void;
136
+ onMouseDown?: (e: React.MouseEvent) => void;
137
+ /** Pass-through id for ARIA wiring (used by typeahead). */
138
+ htmlId?: string;
139
+ }
140
+ declare function CommandTokenView({ id, kind, label, description, icon, tag, variant, selected, onMouseEnter, onMouseDown, htmlId, }: CommandTokenViewProps): react_jsx_runtime.JSX.Element;
141
+
142
+ interface LexicalChatInputHandle {
143
+ /** Clear the editor contents and reset history. */
144
+ clear: () => void;
145
+ /** Programmatically submit the current editor contents. */
146
+ submit: () => void;
147
+ /** Focus the editor. */
148
+ focus: () => void;
149
+ }
150
+ interface LexicalChatInputProps {
151
+ placeholder?: string;
152
+ disabled?: boolean;
153
+ className?: string;
154
+ /** Tailwind classes applied to the inner ContentEditable element. */
155
+ inputClassName?: string;
156
+ /** Slot for additional Lexical plugins (mounted inside LexicalComposer). */
157
+ children?: ReactNode;
158
+ /**
159
+ * Called whenever the editor's plain-text projection changes. Use this to
160
+ * gate a parent-rendered submit button on `text.trim().length > 0`.
161
+ */
162
+ onChange?: (payload: ChatComposerSubmitPayload) => void;
163
+ /** Called when the user presses Enter (without Shift). */
164
+ onSubmit: (payload: ChatComposerSubmitPayload) => void | Promise<void>;
165
+ /**
166
+ * Optional slash-command typeahead. When omitted, the editor behaves like
167
+ * a plain rich-text input.
168
+ */
169
+ commandProvider?: CommandProvider | null;
170
+ /**
171
+ * Multiple typeahead providers, one per trigger character (e.g. `/` for
172
+ * skills + modes, `@` for ad accounts). When supplied, this takes
173
+ * precedence over the singular `commandProvider`. Each provider mounts its
174
+ * own `CommandTokenPlugin` instance.
175
+ */
176
+ commandProviders?: CommandProvider[];
177
+ }
178
+ declare const LexicalChatInput: react.ForwardRefExoticComponent<LexicalChatInputProps & react.RefAttributes<LexicalChatInputHandle>>;
179
+
180
+ export { $createCommandTokenNode, $isCommandTokenNode, COMMAND_TOKEN_REGEX, ChatComposerCommand, ChatComposerSubmitPayload, CommandProvider, CommandTokenNode, CommandTokenPlugin, type CommandTokenPluginProps, CommandTokenView, type CommandTokenViewProps, type InlineCommandTokenMatch, LexicalChatInput, type LexicalChatInputHandle, type LexicalChatInputProps, type SerializedCommandTokenNode, findInlineCommandTokens };
@@ -0,0 +1,2 @@
1
+ export{d as $createCommandTokenNode,e as $isCommandTokenNode,f as COMMAND_TOKEN_REGEX,c as CommandTokenNode,h as CommandTokenPlugin,b as CommandTokenView,i as LexicalChatInput,g as findInlineCommandTokens}from'../chunk-IUCKTDTZ.js';//# sourceMappingURL=index.js.map
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -1,8 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
- import { C as ChatMessage, P as ParticipantRole } from '../message-D3D59U_Q.js';
5
- import { d as VisualizationActionEvent } from '../streaming-Q8hp5ev4.js';
4
+ import { C as ChatMessage, b as ParticipantRole } from '../message-D2ElX5k7.js';
5
+ import { V as VisualizationActionEvent } from '../streaming-B_u_jno6.js';
6
6
 
7
7
  interface ChatContextValue {
8
8
  /** List of messages in the conversation */
@@ -23,6 +23,15 @@ interface ChatContextValue {
23
23
  customData?: Record<string, unknown>;
24
24
  /** Callback when user interacts with a visualization (form submit, card action, etc.) */
25
25
  onVisualizationAction?: (event: VisualizationActionEvent) => void;
26
+ /** Resolve how to render an inline command-token chip (e.g. an
27
+ * `@<id>:ad-account` mention). Wire format only carries id + kind, so the
28
+ * host app supplies the display info. Returning `tag` replaces the default
29
+ * uppercase kind pill (e.g. a platform logo). Returning `label` overrides
30
+ * the id text. */
31
+ resolveCommandToken?: (id: string, kind: string) => {
32
+ label?: string;
33
+ tag?: ReactNode;
34
+ } | undefined;
26
35
  }
27
36
  declare const ChatContext: react.Context<ChatContextValue | null>;
28
37
  interface ChatProviderProps {
@@ -36,8 +45,12 @@ interface ChatProviderProps {
36
45
  onRetryLastMessage?: () => Promise<void>;
37
46
  customData?: Record<string, unknown>;
38
47
  onVisualizationAction?: (event: VisualizationActionEvent) => void;
48
+ resolveCommandToken?: (id: string, kind: string) => {
49
+ label?: string;
50
+ tag?: ReactNode;
51
+ } | undefined;
39
52
  }
40
- declare function ChatProvider({ children, messages, isStreaming, streamingMessageId, viewerRole, onSendMessage, onStopStreaming, onRetryLastMessage, customData, onVisualizationAction, }: ChatProviderProps): react_jsx_runtime.JSX.Element;
53
+ declare function ChatProvider({ children, messages, isStreaming, streamingMessageId, viewerRole, onSendMessage, onStopStreaming, onRetryLastMessage, customData, onVisualizationAction, resolveCommandToken, }: ChatProviderProps): react_jsx_runtime.JSX.Element;
41
54
  declare function useChatContext(): ChatContextValue;
42
55
 
43
56
  export { ChatContext, type ChatContextValue, ChatProvider, type ChatProviderProps, useChatContext };
@@ -1,2 +1,2 @@
1
- export{a as ChatContext,b as ChatProvider,c as useChatContext}from'../chunk-OCKHJ4WO.js';//# sourceMappingURL=index.js.map
1
+ export{a as ChatContext,b as ChatProvider,c as useChatContext}from'../chunk-NKLA5PPB.js';//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { RefObject, KeyboardEvent } from 'react';
3
- import { b as StreamingOptions, a as StreamChunk } from '../streaming-Q8hp5ev4.js';
4
- import { B as BrandingData } from '../branding-SzYU4ncD.js';
3
+ import { m as StreamingOptions, S as StreamChunk } from '../streaming-B_u_jno6.js';
4
+ import { B as BrandingData } from '../branding-NieTEGQf.js';
5
5
 
6
6
  interface UseAutoScrollOptions {
7
7
  /** Whether auto-scroll is enabled */
@@ -1,2 +1,2 @@
1
- export{b as useAttachments,a as useStreaming}from'../chunk-WG77GQR3.js';export{a as useScrollLock}from'../chunk-D2PFIJNZ.js';export{a as useAutoScroll,b as useMessageComposer}from'../chunk-4WWJTYYA.js';export{b as useBrandingCSSVars}from'../chunk-NSTK5EUQ.js';//# sourceMappingURL=index.js.map
1
+ export{b as useAttachments,a as useStreaming}from'../chunk-WG77GQR3.js';export{a as useScrollLock}from'../chunk-D2PFIJNZ.js';export{a as useAutoScroll,b as useMessageComposer}from'../chunk-4WWJTYYA.js';export{b as useBrandingCSSVars}from'../chunk-QECTWT2H.js';//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.d.ts CHANGED
@@ -1,14 +1,15 @@
1
- export { A as Attachment, C as ChatMessage, a as MemoryFeedbackType, M as MessageData, b as MessageError, c as Participant, P as ParticipantRole, R as ReasoningChunk, S as SourceReference, d as SourceTypeConfig, e as SuggestedAction, f as SuggestedActionType, i as isMemoryCitation } from './message-D3D59U_Q.js';
2
- export { a as StreamChunk, b as StreamingOptions, c as StreamingState } from './streaming-Q8hp5ev4.js';
3
- export { B as BrandingData } from './branding-SzYU4ncD.js';
1
+ export { A as Attachment, C as ChatMessage, M as MessageData, a as MessageError, P as Participant, b as ParticipantRole, R as ReasoningChunk, S as SourceReference, c as SourceTypeConfig, d as SuggestedAction, e as SuggestedActionType } from './message-D2ElX5k7.js';
2
+ export { S as StreamChunk, m as StreamingOptions, n as StreamingState } from './streaming-B_u_jno6.js';
3
+ export { B as BrandingData } from './branding-NieTEGQf.js';
4
4
  export { ChatContext, ChatContextValue, ChatProvider, ChatProviderProps, useChatContext } from './context/index.js';
5
5
  export { useAttachments, useAutoScroll, useBrandingCSSVars, useMessageComposer, useScrollLock, useStreaming } from './hooks/index.js';
6
- export { A as AvatarPrimitive, C as ComposerContext, a as ComposerInput, b as ComposerSubmit, M as MessageComposerPrimitive, c as MessageContentPrimitive, d as MessageContext, e as MessagePrimitive, f as MessageTimestampPrimitive, u as useComposer, g as useMessage } from './avatar-CAmTN1L7.js';
6
+ export { A as AvatarPrimitive, C as ComposerContext, b as ComposerInput, d as ComposerSubmit, f as MessageComposerPrimitive, h as MessageContentPrimitive, j as MessageContext, M as MessagePrimitive, l as MessageTimestampPrimitive, u as useComposer, n as useMessage } from './avatar-DnLePg72.js';
7
7
  export { ActionButton, MessageList as MessageListPrimitive, StreamingText as StreamingTextPrimitive, SuggestedActionsContext, SuggestedActions as SuggestedActionsPrimitive, TypingIndicator as TypingIndicatorPrimitive, useSuggestedActions } from './primitives/index.js';
8
- export { A as AttachmentPreview, a as Avatar, C as ChatContainer, b as ChatLayout, M as MarkdownContent, c as Message, d as MessageActionBar, e as MessageComposer, f as MessageList, S as ScrollToBottomButton, g as StreamingText, h as SuggestedActions, T as ToolStatusIndicator, i as TypingIndicator, W as WelcomeScreen } from './WelcomeScreen-D32Tsu6G.js';
8
+ export { A as AttachmentPreview, b as Avatar, C as ChatContainer, e as ChatLayout, M as MarkdownContent, h as Message, i as MessageActionBar, k as MessageComposer, m as MessageList, S as ScrollToBottomButton, q as StreamingText, s as SuggestedActions, u as ToolStatusIndicator, w as TypingIndicator, W as WelcomeScreen } from './WelcomeScreen-CVxniqqK.js';
9
9
  import { ClassValue } from 'clsx';
10
10
  import 'react/jsx-runtime';
11
11
  import 'react';
12
+ import './types-DeHbndy0.js';
12
13
 
13
14
  /**
14
15
  * Utility function to merge Tailwind CSS classes with proper precedence.
@@ -51,9 +52,12 @@ type ContentPart = {
51
52
  } | {
52
53
  type: "media";
53
54
  id: string;
55
+ } | {
56
+ type: "sa";
57
+ id: string;
54
58
  };
55
59
  /**
56
- * Parse content and split it by inline markers ([VIZ:id] and [MEDIA:id]).
60
+ * Parse content and split it by inline markers ([VIZ:id], [MEDIA:id], and [SA:id]).
57
61
  */
58
62
  declare function parseContentWithInlineMarkers(content: string): ContentPart[];
59
63
 
@@ -101,6 +105,14 @@ declare const chatTokens: {
101
105
  readonly secondary: "var(--chat-secondary, #56C18A)";
102
106
  readonly error: "var(--chat-error, #B1001B)";
103
107
  readonly warning: "var(--chat-warning, #DD9652)";
108
+ /**
109
+ * Accent for in-progress / live indicators in the reasoning panel:
110
+ * running halo, animated caret, header wave, rail-flow gradient, and
111
+ * active-row wash. Falls back to --chat-primary so existing usage is
112
+ * unchanged. Override independently when the brand primary is neutral
113
+ * and would otherwise blend into completed-state visuals.
114
+ */
115
+ readonly activity: "var(--chat-activity, var(--chat-primary, #106997))";
104
116
  readonly messageBg: "var(--chat-message-bg, rgba(0, 0, 0, 0.03))";
105
117
  readonly userMessageBg: "var(--chat-user-message-bg, var(--chat-primary, #106997))";
106
118
  readonly userMessageText: "var(--chat-user-message-text, #ffffff)";
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export{c as AttachmentPreview,d as Avatar,e as ChatContainer,ba as ChatLayout,g as MarkdownContent,V as Message,l as MessageActionBar,W as MessageComposer,Y as MessageList,X as ScrollToBottomButton,C as StreamingText,D as SuggestedActions,aa as ToolStatusIndicator,_ as TypingIndicator,ca as WelcomeScreen,b as cn,a as isMemoryCitation,U as parseContentWithInlineMarkers}from'./chunk-VDFIXLNO.js';export{q as ActionButton,l as AvatarPrimitive,g as ComposerContext,j as ComposerInput,k as ComposerSubmit,i as MessageComposerPrimitive,d as MessageContentPrimitive,a as MessageContext,f as MessageListPrimitive,c as MessagePrimitive,e as MessageTimestampPrimitive,m as StreamingTextPrimitive,n as SuggestedActionsContext,p as SuggestedActionsPrimitive,r as TypingIndicatorPrimitive,h as useComposer,b as useMessage,o as useSuggestedActions}from'./chunk-6RN7SUWT.js';export{b as useAttachments,a as useStreaming}from'./chunk-WG77GQR3.js';export{a as useScrollLock}from'./chunk-D2PFIJNZ.js';export{a as useAutoScroll,b as useMessageComposer}from'./chunk-4WWJTYYA.js';export{a as ChatContext,b as ChatProvider,c as useChatContext}from'./chunk-OCKHJ4WO.js';export{a as getContrastTextColor,b as useBrandingCSSVars}from'./chunk-NSTK5EUQ.js';var i={hour:"numeric",minute:"2-digit",hour12:true},m={month:"short",day:"numeric"},ae={...m,year:"numeric",...i};function p(t){let e=typeof t=="string"?new Date(t):t,r=new Date;return e.getDate()===r.getDate()&&e.getMonth()===r.getMonth()&&e.getFullYear()===r.getFullYear()?e.toLocaleTimeString("en-US",i):e.getFullYear()===r.getFullYear()?`${e.toLocaleDateString("en-US",m)}, ${e.toLocaleTimeString("en-US",i)}`:e.toLocaleDateString("en-US",ae)}function oe(t){let e=typeof t=="string"?new Date(t):t,g=new Date().getTime()-e.getTime(),s=Math.floor(g/1e3),a=Math.floor(s/60),o=Math.floor(a/60),n=Math.floor(o/24);return s<60?"just now":a<60?`${a} minute${a===1?"":"s"} ago`:o<24?`${o} hour${o===1?"":"s"} ago`:n<7?`${n} day${n===1?"":"s"} ago`:p(e)}var se={spacing:{messageBetween:"1rem",messagePx:"0.875rem",messagePy:"0.625rem",container:"1rem",composerPadding:"1rem"},typography:{message:{fontSize:"1rem",lineHeight:1.5,letterSpacing:"0px"},caption:{fontSize:"0.875rem",lineHeight:1.4},small:{fontSize:"0.8125rem",lineHeight:1.3}},borderRadius:{message:"0.5rem",input:"1rem",panel:"0.5rem",button:"0.5rem",chip:"0.25rem"},colors:{primary:"var(--chat-primary, #106997)",secondary:"var(--chat-secondary, #56C18A)",error:"var(--chat-error, #B1001B)",warning:"var(--chat-warning, #DD9652)",messageBg:"var(--chat-message-bg, rgba(0, 0, 0, 0.03))",userMessageBg:"var(--chat-user-message-bg, var(--chat-primary, #106997))",userMessageText:"var(--chat-user-message-text, #ffffff)",panelBg:"var(--chat-panel-bg, rgba(0, 0, 0, 0.02))",panelBorder:"var(--chat-panel-border, rgba(0, 0, 0, 0.06))",border:"var(--chat-border, rgba(0, 0, 0, 0.06))",borderHover:"var(--chat-border-hover, rgba(0, 0, 0, 0.12))",text:"var(--chat-text, #1D2033)",subtle:"var(--chat-text-subtle, rgba(0, 0, 0, 0.5))",placeholder:"var(--chat-placeholder, rgba(0, 0, 0, 0.4))",status:{pending:{main:"rgba(0, 0, 0, 0.3)",bg:"rgba(0, 0, 0, 0.05)"},running:{main:"rgb(99, 102, 241)",bg:"rgba(99, 102, 241, 0.08)"},completed:{main:"rgb(16, 185, 129)",bg:"rgba(16, 185, 129, 0.08)"},failed:{main:"rgb(239, 68, 68)",bg:"rgba(239, 68, 68, 0.08)"}}},shadows:{subtle:"0 1px 2px rgba(0, 0, 0, 0.04)",input:"0 2px 8px rgba(0, 0, 0, 0.08)",inputFocus:"0 4px 16px rgba(0, 0, 0, 0.12)",button:"0 1px 3px rgba(0, 0, 0, 0.08)",buttonHover:"0 2px 6px rgba(0, 0, 0, 0.12)",primary:"0 2px 6px rgba(16, 105, 151, 0.3)",primaryHover:"0 4px 12px rgba(16, 105, 151, 0.4)"},animations:{messageEntrance:{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{duration:.3,ease:[.4,0,.2,1]}},fadeIn:{initial:{opacity:0},animate:{opacity:1},transition:{duration:.2}}}};export{se as chatTokens,p as formatMessageTime,oe as formatRelativeTime};//# sourceMappingURL=index.js.map
1
+ export{a as AttachmentPreview,b as Avatar,c as ChatContainer,aa as ChatLayout,e as MarkdownContent,U as Message,k as MessageActionBar,V as MessageComposer,X as MessageList,W as ScrollToBottomButton,w as StreamingText,x as SuggestedActions,$ as ToolStatusIndicator,Z as TypingIndicator,ba as WelcomeScreen,T as parseContentWithInlineMarkers}from'./chunk-ERJKVQQT.js';export{q as ActionButton,l as AvatarPrimitive,g as ComposerContext,j as ComposerInput,k as ComposerSubmit,i as MessageComposerPrimitive,d as MessageContentPrimitive,a as MessageContext,f as MessageListPrimitive,c as MessagePrimitive,e as MessageTimestampPrimitive,m as StreamingTextPrimitive,n as SuggestedActionsContext,p as SuggestedActionsPrimitive,r as TypingIndicatorPrimitive,h as useComposer,b as useMessage,o as useSuggestedActions}from'./chunk-6RN7SUWT.js';export{b as useAttachments,a as useStreaming}from'./chunk-WG77GQR3.js';export{a as useScrollLock}from'./chunk-D2PFIJNZ.js';export{a as useAutoScroll,b as useMessageComposer}from'./chunk-4WWJTYYA.js';export{a as ChatContext,b as ChatProvider,c as useChatContext}from'./chunk-NKLA5PPB.js';export{a as chatTokens}from'./chunk-NG4HKXYB.js';export{a as getContrastTextColor,b as useBrandingCSSVars}from'./chunk-QECTWT2H.js';export{a as cn}from'./chunk-IUCKTDTZ.js';var i={hour:"numeric",minute:"2-digit",hour12:true},m={month:"short",day:"numeric"},se={...m,year:"numeric",...i};function u(t){let e=typeof t=="string"?new Date(t):t,o=new Date;return e.getDate()===o.getDate()&&e.getMonth()===o.getMonth()&&e.getFullYear()===o.getFullYear()?e.toLocaleTimeString("en-US",i):e.getFullYear()===o.getFullYear()?`${e.toLocaleDateString("en-US",m)}, ${e.toLocaleTimeString("en-US",i)}`:e.toLocaleDateString("en-US",se)}function re(t){let e=typeof t=="string"?new Date(t):t,g=new Date().getTime()-e.getTime(),n=Math.floor(g/1e3),s=Math.floor(n/60),r=Math.floor(s/60),a=Math.floor(r/24);return n<60?"just now":s<60?`${s} minute${s===1?"":"s"} ago`:r<24?`${r} hour${r===1?"":"s"} ago`:a<7?`${a} day${a===1?"":"s"} ago`:u(e)}export{u as formatMessageTime,re as formatRelativeTime};//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/format-date.ts","../src/styles/tokens.ts"],"names":["TIME_FORMAT","DATE_FORMAT","FULL_FORMAT","formatMessageTime","date","d","now","formatRelativeTime","diffMs","diffSeconds","diffMinutes","diffHours","diffDays","chatTokens"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Format a date for display in chat messages.\n */\n\nconst TIME_FORMAT: Intl.DateTimeFormatOptions = {\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n};\n\nconst DATE_FORMAT: Intl.DateTimeFormatOptions = {\n month: \"short\",\n day: \"numeric\",\n};\n\nconst FULL_FORMAT: Intl.DateTimeFormatOptions = {\n ...DATE_FORMAT,\n year: \"numeric\",\n ...TIME_FORMAT,\n};\n\n/**\n * Format a timestamp for display.\n * - Today: \"2:30 PM\"\n * - This year: \"Dec 15, 2:30 PM\"\n * - Other years: \"Dec 15, 2024, 2:30 PM\"\n */\nexport function formatMessageTime(date: Date | string): string {\n const d = typeof date === \"string\" ? new Date(date) : date;\n const now = new Date();\n\n const isToday =\n d.getDate() === now.getDate() &&\n d.getMonth() === now.getMonth() &&\n d.getFullYear() === now.getFullYear();\n\n if (isToday) {\n return d.toLocaleTimeString(\"en-US\", TIME_FORMAT);\n }\n\n const isThisYear = d.getFullYear() === now.getFullYear();\n\n if (isThisYear) {\n return `${d.toLocaleDateString(\"en-US\", DATE_FORMAT)}, ${d.toLocaleTimeString(\"en-US\", TIME_FORMAT)}`;\n }\n\n return d.toLocaleDateString(\"en-US\", FULL_FORMAT);\n}\n\n/**\n * Format a relative time (e.g., \"2 minutes ago\").\n */\nexport function formatRelativeTime(date: Date | string): string {\n const d = typeof date === \"string\" ? new Date(date) : date;\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffSeconds = Math.floor(diffMs / 1000);\n const diffMinutes = Math.floor(diffSeconds / 60);\n const diffHours = Math.floor(diffMinutes / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffSeconds < 60) {\n return \"just now\";\n }\n\n if (diffMinutes < 60) {\n return `${diffMinutes} minute${diffMinutes === 1 ? \"\" : \"s\"} ago`;\n }\n\n if (diffHours < 24) {\n return `${diffHours} hour${diffHours === 1 ? \"\" : \"s\"} ago`;\n }\n\n if (diffDays < 7) {\n return `${diffDays} day${diffDays === 1 ? \"\" : \"s\"} ago`;\n }\n\n return formatMessageTime(d);\n}\n","/**\n * Design tokens for the chat UI.\n * These map to CSS custom properties for easy theming.\n */\n\nexport const chatTokens = {\n spacing: {\n /** Vertical spacing between messages (16px) */\n messageBetween: \"1rem\",\n /** Message bubble horizontal padding (14px) */\n messagePx: \"0.875rem\",\n /** Message bubble vertical padding (10px) */\n messagePy: \"0.625rem\",\n /** Container padding (16px) */\n container: \"1rem\",\n /** Composer padding (16px) */\n composerPadding: \"1rem\",\n },\n\n typography: {\n message: {\n fontSize: \"1rem\",\n lineHeight: 1.5,\n letterSpacing: \"0px\",\n },\n caption: {\n fontSize: \"0.875rem\",\n lineHeight: 1.4,\n },\n small: {\n fontSize: \"0.8125rem\",\n lineHeight: 1.3,\n },\n },\n\n borderRadius: {\n message: \"0.5rem\",\n input: \"1rem\",\n panel: \"0.5rem\",\n button: \"0.5rem\",\n chip: \"0.25rem\",\n },\n\n colors: {\n // CSS custom property references\n primary: \"var(--chat-primary, #106997)\",\n secondary: \"var(--chat-secondary, #56C18A)\",\n error: \"var(--chat-error, #B1001B)\",\n warning: \"var(--chat-warning, #DD9652)\",\n\n // Message backgrounds\n messageBg: \"var(--chat-message-bg, rgba(0, 0, 0, 0.03))\",\n userMessageBg: \"var(--chat-user-message-bg, var(--chat-primary, #106997))\",\n userMessageText: \"var(--chat-user-message-text, #ffffff)\",\n\n // Panel backgrounds\n panelBg: \"var(--chat-panel-bg, rgba(0, 0, 0, 0.02))\",\n panelBorder: \"var(--chat-panel-border, rgba(0, 0, 0, 0.06))\",\n\n // Borders\n border: \"var(--chat-border, rgba(0, 0, 0, 0.06))\",\n borderHover: \"var(--chat-border-hover, rgba(0, 0, 0, 0.12))\",\n\n // Text\n text: \"var(--chat-text, #1D2033)\",\n subtle: \"var(--chat-text-subtle, rgba(0, 0, 0, 0.5))\",\n placeholder: \"var(--chat-placeholder, rgba(0, 0, 0, 0.4))\",\n\n // Status colors\n status: {\n pending: {\n main: \"rgba(0, 0, 0, 0.3)\",\n bg: \"rgba(0, 0, 0, 0.05)\",\n },\n running: {\n main: \"rgb(99, 102, 241)\",\n bg: \"rgba(99, 102, 241, 0.08)\",\n },\n completed: {\n main: \"rgb(16, 185, 129)\",\n bg: \"rgba(16, 185, 129, 0.08)\",\n },\n failed: {\n main: \"rgb(239, 68, 68)\",\n bg: \"rgba(239, 68, 68, 0.08)\",\n },\n },\n },\n\n shadows: {\n subtle: \"0 1px 2px rgba(0, 0, 0, 0.04)\",\n input: \"0 2px 8px rgba(0, 0, 0, 0.08)\",\n inputFocus: \"0 4px 16px rgba(0, 0, 0, 0.12)\",\n button: \"0 1px 3px rgba(0, 0, 0, 0.08)\",\n buttonHover: \"0 2px 6px rgba(0, 0, 0, 0.12)\",\n primary: \"0 2px 6px rgba(16, 105, 151, 0.3)\",\n primaryHover: \"0 4px 12px rgba(16, 105, 151, 0.4)\",\n },\n\n animations: {\n messageEntrance: {\n initial: { opacity: 0, y: 8 },\n animate: { opacity: 1, y: 0 },\n transition: { duration: 0.3, ease: [0.4, 0, 0.2, 1] },\n },\n fadeIn: {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n transition: { duration: 0.2 },\n },\n },\n} as const;\n\nexport type ChatTokens = typeof chatTokens;\n"]}
1
+ {"version":3,"sources":["../src/utils/format-date.ts"],"names":["TIME_FORMAT","DATE_FORMAT","FULL_FORMAT","formatMessageTime","date","d","now","formatRelativeTime","diffMs","diffSeconds","diffMinutes","diffHours","diffDays"],"mappings":"4wCAIA,IAAMA,EAA0C,CAC9C,IAAA,CAAM,UACN,MAAA,CAAQ,SAAA,CACR,OAAQ,IACV,CAAA,CAEMC,CAAAA,CAA0C,CAC9C,MAAO,OAAA,CACP,GAAA,CAAK,SACP,CAAA,CAEMC,EAAAA,CAA0C,CAC9C,GAAGD,CAAAA,CACH,IAAA,CAAM,SAAA,CACN,GAAGD,CACL,CAAA,CAQO,SAASG,CAAAA,CAAkBC,CAAAA,CAA6B,CAC7D,IAAMC,CAAAA,CAAI,OAAOD,CAAAA,EAAS,SAAW,IAAI,IAAA,CAAKA,CAAI,CAAA,CAAIA,CAAAA,CAChDE,EAAM,IAAI,IAAA,CAOhB,OAJED,CAAAA,CAAE,SAAQ,GAAMC,CAAAA,CAAI,SAAQ,EAC5BD,CAAAA,CAAE,UAAS,GAAMC,CAAAA,CAAI,QAAA,EAAS,EAC9BD,EAAE,WAAA,EAAY,GAAMC,EAAI,WAAA,EAAY,CAG7BD,EAAE,kBAAA,CAAmB,OAAA,CAASL,CAAW,CAAA,CAG/BK,EAAE,WAAA,EAAY,GAAMC,EAAI,WAAA,EAAY,CAG9C,GAAGD,CAAAA,CAAE,kBAAA,CAAmB,QAASJ,CAAW,CAAC,KAAKI,CAAAA,CAAE,kBAAA,CAAmB,QAASL,CAAW,CAAC,GAG9FK,CAAAA,CAAE,kBAAA,CAAmB,OAAA,CAASH,EAAW,CAClD,CAKO,SAASK,GAAmBH,CAAAA,CAA6B,CAC9D,IAAMC,CAAAA,CAAI,OAAOD,CAAAA,EAAS,QAAA,CAAW,IAAI,IAAA,CAAKA,CAAI,EAAIA,CAAAA,CAEhDI,CAAAA,CADM,IAAI,IAAA,EAAK,CACF,OAAA,EAAQ,CAAIH,EAAE,OAAA,EAAQ,CACnCI,EAAc,IAAA,CAAK,KAAA,CAAMD,EAAS,GAAI,CAAA,CACtCE,CAAAA,CAAc,IAAA,CAAK,MAAMD,CAAAA,CAAc,EAAE,EACzCE,CAAAA,CAAY,IAAA,CAAK,MAAMD,CAAAA,CAAc,EAAE,CAAA,CACvCE,CAAAA,CAAW,KAAK,KAAA,CAAMD,CAAAA,CAAY,EAAE,CAAA,CAE1C,OAAIF,EAAc,EAAA,CACT,UAAA,CAGLC,CAAAA,CAAc,EAAA,CACT,GAAGA,CAAW,CAAA,OAAA,EAAUA,IAAgB,CAAA,CAAI,EAAA,CAAK,GAAG,CAAA,IAAA,CAAA,CAGzDC,CAAAA,CAAY,EAAA,CACP,CAAA,EAAGA,CAAS,CAAA,KAAA,EAAQA,CAAAA,GAAc,EAAI,EAAA,CAAK,GAAG,OAGnDC,CAAAA,CAAW,CAAA,CACN,GAAGA,CAAQ,CAAA,IAAA,EAAOA,IAAa,CAAA,CAAI,EAAA,CAAK,GAAG,CAAA,IAAA,CAAA,CAG7CT,CAAAA,CAAkBE,CAAC,CAC5B","file":"index.js","sourcesContent":["/**\n * Format a date for display in chat messages.\n */\n\nconst TIME_FORMAT: Intl.DateTimeFormatOptions = {\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n};\n\nconst DATE_FORMAT: Intl.DateTimeFormatOptions = {\n month: \"short\",\n day: \"numeric\",\n};\n\nconst FULL_FORMAT: Intl.DateTimeFormatOptions = {\n ...DATE_FORMAT,\n year: \"numeric\",\n ...TIME_FORMAT,\n};\n\n/**\n * Format a timestamp for display.\n * - Today: \"2:30 PM\"\n * - This year: \"Dec 15, 2:30 PM\"\n * - Other years: \"Dec 15, 2024, 2:30 PM\"\n */\nexport function formatMessageTime(date: Date | string): string {\n const d = typeof date === \"string\" ? new Date(date) : date;\n const now = new Date();\n\n const isToday =\n d.getDate() === now.getDate() &&\n d.getMonth() === now.getMonth() &&\n d.getFullYear() === now.getFullYear();\n\n if (isToday) {\n return d.toLocaleTimeString(\"en-US\", TIME_FORMAT);\n }\n\n const isThisYear = d.getFullYear() === now.getFullYear();\n\n if (isThisYear) {\n return `${d.toLocaleDateString(\"en-US\", DATE_FORMAT)}, ${d.toLocaleTimeString(\"en-US\", TIME_FORMAT)}`;\n }\n\n return d.toLocaleDateString(\"en-US\", FULL_FORMAT);\n}\n\n/**\n * Format a relative time (e.g., \"2 minutes ago\").\n */\nexport function formatRelativeTime(date: Date | string): string {\n const d = typeof date === \"string\" ? new Date(date) : date;\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffSeconds = Math.floor(diffMs / 1000);\n const diffMinutes = Math.floor(diffSeconds / 60);\n const diffHours = Math.floor(diffMinutes / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffSeconds < 60) {\n return \"just now\";\n }\n\n if (diffMinutes < 60) {\n return `${diffMinutes} minute${diffMinutes === 1 ? \"\" : \"s\"} ago`;\n }\n\n if (diffHours < 24) {\n return `${diffHours} hour${diffHours === 1 ? \"\" : \"s\"} ago`;\n }\n\n if (diffDays < 7) {\n return `${diffDays} day${diffDays === 1 ? \"\" : \"s\"} ago`;\n }\n\n return formatMessageTime(d);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { S as StreamingChunk, C as ClarificationData, M as MediaChunkData } from './streaming-Q8hp5ev4.js';
1
+ import { k as StreamingChunk, d as ClarificationData, s as ToolApprovalData, M as MediaChunkData, A as ArtifactChunkData } from './streaming-B_u_jno6.js';
2
2
 
3
3
  /**
4
4
  * Citation source types for AI-generated content.
@@ -22,8 +22,6 @@ interface SourceTypeConfig {
22
22
  label: string;
23
23
  color: string;
24
24
  }
25
- type MemoryFeedbackType = "relevant" | "not_relevant";
26
- declare function isMemoryCitation(source: SourceReference): boolean;
27
25
 
28
26
  type ParticipantRole = "user" | "assistant" | "system";
29
27
  interface Participant {
@@ -77,8 +75,11 @@ interface ChatMessage extends MessageData {
77
75
  reasoning?: StreamingChunk[];
78
76
  citations?: SourceReference[];
79
77
  pendingClarification?: ClarificationData;
78
+ pendingToolApproval?: ToolApprovalData;
80
79
  /** Inline media (images/videos) to render within message content */
81
80
  medias?: MediaChunkData[];
81
+ /** Downloadable artifacts (PDFs, HTMLs) produced by tool calls in this message */
82
+ artifacts?: ArtifactChunkData[];
82
83
  /** Wall-clock execution time in seconds (persisted after streaming completes) */
83
84
  executionTime?: number;
84
85
  }
@@ -89,4 +90,4 @@ interface ReasoningChunk {
89
90
  timestamp: string | Date;
90
91
  }
91
92
 
92
- export { type Attachment as A, type ChatMessage as C, type MessageData as M, type ParticipantRole as P, type ReasoningChunk as R, type SourceReference as S, type MemoryFeedbackType as a, type MessageError as b, type Participant as c, type SourceTypeConfig as d, type SuggestedAction as e, type SuggestedActionType as f, isMemoryCitation as i };
93
+ export type { Attachment as A, ChatMessage as C, MessageData as M, Participant as P, ReasoningChunk as R, SourceReference as S, MessageError as a, ParticipantRole as b, SourceTypeConfig as c, SuggestedAction as d, SuggestedActionType as e };
@@ -1,8 +1,8 @@
1
- export { A as Avatar, h as AvatarProps, C as ComposerContext, a as ComposerInput, i as ComposerInputProps, b as ComposerSubmit, j as ComposerSubmitProps, e as Message, M as MessageComposer, k as MessageComposerProps, c as MessageContent, l as MessageContentProps, d as MessageContext, m as MessageProps, f as MessageTimestamp, n as MessageTimestampProps, u as useComposer, g as useMessage } from '../avatar-CAmTN1L7.js';
1
+ export { A as Avatar, a as AvatarProps, C as ComposerContext, b as ComposerInput, c as ComposerInputProps, d as ComposerSubmit, e as ComposerSubmitProps, M as Message, f as MessageComposer, g as MessageComposerProps, h as MessageContent, i as MessageContentProps, j as MessageContext, k as MessageProps, l as MessageTimestamp, m as MessageTimestampProps, u as useComposer, n as useMessage } from '../avatar-DnLePg72.js';
2
2
  import * as react from 'react';
3
3
  import { HTMLAttributes, ReactNode, ButtonHTMLAttributes } from 'react';
4
- import { e as SuggestedAction } from '../message-D3D59U_Q.js';
5
- import '../streaming-Q8hp5ev4.js';
4
+ import { d as SuggestedAction } from '../message-D2ElX5k7.js';
5
+ import '../streaming-B_u_jno6.js';
6
6
 
7
7
  interface MessageListProps extends HTMLAttributes<HTMLDivElement> {
8
8
  /** Messages to render */