@ensembleapp/client-sdk 0.0.54 → 0.0.56

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/README.md CHANGED
@@ -63,6 +63,80 @@ function CustomChat() {
63
63
  }
64
64
  ```
65
65
 
66
+ ### Reading token usage
67
+
68
+ The server streams token/usage stats as a `data-usage` part. You can read them
69
+ three ways.
70
+
71
+ **1. `<ChatWidget>`: the `onUsage` callback**
72
+
73
+ ```tsx
74
+ import { ChatWidget, type ChatUsageData } from '@ensembleapp/client-sdk'
75
+
76
+ <ChatWidget
77
+ api={{ baseUrl: '/api', token: 'your-jwt-token' }}
78
+ agentId="agent-234"
79
+ threadId="user-123"
80
+ onUsage={(usage: ChatUsageData) => {
81
+ console.log(usage.inputTokens, usage.outputTokens)
82
+ console.log(usage.totalMessageCount, usage.messageHistoryLimit)
83
+ }}
84
+ />
85
+ ```
86
+
87
+ Or, to render the built-in counter (`↑ N in · ↓ N out`) above the input without
88
+ writing any code, set `showTokenUsage`:
89
+
90
+ ```tsx
91
+ <ChatWidget api={/* ... */} agentId="..." threadId="..." showTokenUsage />
92
+ ```
93
+
94
+ **2. `useChat` hook: the `usage` return value**
95
+
96
+ `usage` is reactive state (the latest turn), so it's the simplest way to render:
97
+
98
+ ```tsx
99
+ import { useChat, type ChatUsageData } from '@ensembleapp/client-sdk'
100
+
101
+ function CustomChat() {
102
+ const { messages, sendMessage, usage } = useChat({ /* ...config */ })
103
+ // ^^^^^ ChatUsageData | null
104
+
105
+ return <div>{usage && `${usage.inputTokens} in / ${usage.outputTokens} out`}</div>
106
+ }
107
+ ```
108
+
109
+ You can also pass `onUsage` to the hook if you prefer the event style.
110
+
111
+ **3. `extractUsageData`: for custom stream handling**
112
+
113
+ If you handle the stream at a lower level (e.g. via `onData`), pull usage out of
114
+ any data part:
115
+
116
+ ```tsx
117
+ import { extractUsageData } from '@ensembleapp/client-sdk'
118
+
119
+ onData: (dataPart) => {
120
+ const usage = extractUsageData(dataPart) // ChatUsageData | null
121
+ if (usage) { /* ... */ }
122
+ }
123
+ ```
124
+
125
+ **`ChatUsageData` shape**
126
+
127
+ ```ts
128
+ interface ChatUsageData {
129
+ inputTokens: number
130
+ outputTokens: number
131
+ maxInputTokens?: number
132
+ maxOutputTokens?: number
133
+ inputTokensPercent?: number
134
+ outputTokensPercent?: number
135
+ totalMessageCount?: number
136
+ messageHistoryLimit?: number
137
+ }
138
+ ```
139
+
66
140
  ## API Reference
67
141
 
68
142
  ### ChatWidget Props
@@ -72,6 +146,9 @@ function CustomChat() {
72
146
  - `onMessage?` (function): Callback when a new message is received
73
147
  - `onError?` (function): Callback when an error occurs
74
148
  - `onFinish?` (function): Callback when a conversation finishes
149
+ - `onUsage?` ((usage: ChatUsageData) => void): Callback with token/usage stats as they stream
150
+ - `onData?` ((dataPart) => void): Callback for every raw stream data part
151
+ - `showTokenUsage?` (boolean): Show the built-in input/output token counter above the input (default: false)
75
152
  - `className?` (string): Additional CSS classes
76
153
  - `placeholder?` (string): Input placeholder text
77
154
  - `welcomeMessage?` (string): Initial welcome message
@@ -81,10 +158,10 @@ function CustomChat() {
81
158
  ```tsx
82
159
  const {
83
160
  messages, // Array of chat messages
84
- isLoading, // Boolean indicating if request is in progress
85
- isError, // Boolean indicating if there's an error
161
+ status, // Current request status
86
162
  sendMessage, // Function to send a message
87
163
  stop, // Function to stop current request
88
164
  setMessages, // Function to manually set messages
165
+ usage, // ChatUsageData | null (latest token/usage stats)
89
166
  } = useChat(config)
90
167
  ```
package/dist/index.d.ts CHANGED
@@ -63,6 +63,35 @@ interface ApiConfig {
63
63
  /** Agent version selector: 'latest' (default), 'published', or a specific version number */
64
64
  type AgentVersion = 'latest' | 'published' | number;
65
65
  type StructuredMessagePayload = Record<string, unknown>;
66
+ /**
67
+ * Usage stats emitted by the server as a `data-usage` stream part and delivered
68
+ * to the {@link UseChatConfig.onUsage} callback.
69
+ */
70
+ interface ChatUsageData {
71
+ inputTokens: number;
72
+ outputTokens: number;
73
+ maxInputTokens?: number;
74
+ maxOutputTokens?: number;
75
+ inputTokensPercent?: number;
76
+ outputTokensPercent?: number;
77
+ /** Total number of messages in the conversation so far */
78
+ totalMessageCount?: number;
79
+ /** Maximum number of messages allowed in conversation history */
80
+ messageHistoryLimit?: number;
81
+ }
82
+ /**
83
+ * Extract usage stats from a stream data part. The server wraps usage as
84
+ * `{ type: 'data-usage', data: { ...ChatUsageData } }`; returns the full inner
85
+ * payload (including totalMessageCount / messageHistoryLimit) or null if the
86
+ * part is not a usage part.
87
+ */
88
+ declare function extractUsageData(dataPart: unknown): ChatUsageData | null;
89
+ /**
90
+ * Build the GET /chat/messages URL for loading initial history. Appends
91
+ * `?limit=<n>` when `messagesToLoad` is provided (a positive number), otherwise
92
+ * returns the base URL so the server default applies.
93
+ */
94
+ declare function buildMessagesUrl(baseUrl: string, messagesToLoad?: number): string;
66
95
  type UseChatConfig = DeprecatedChatConfig & {
67
96
  /** The server API configuration */
68
97
  api: ApiConfig;
@@ -74,23 +103,18 @@ type UseChatConfig = DeprecatedChatConfig & {
74
103
  agentVersion?: AgentVersion;
75
104
  /** additional context (anything) that needs to be passed to the LLM */
76
105
  dataContext?: unknown;
106
+ /** Number of most-recent messages to load into the chat on open/reload. Defaults to the server's default. */
107
+ messagesToLoad?: number;
77
108
  onError?: (error: Error) => void;
78
109
  /** Called when API returns 401/unauthorized (e.g., token expiry). Return a new token to retry the request. */
79
110
  onAuthError?: () => Promise<string | null>;
80
111
  onFinish?: (message: any) => void;
81
112
  onData?: (data: any) => void;
82
113
  onMessage?: (message: UIMessage) => void;
83
- /** Called when usage data is received (input/output token counts and percentages) */
84
- onUsage?: (usage: {
85
- inputTokens: number;
86
- outputTokens: number;
87
- maxInputTokens?: number;
88
- maxOutputTokens?: number;
89
- inputTokensPercent?: number;
90
- outputTokensPercent?: number;
91
- }) => void;
114
+ /** Called when usage data is received (token counts/percentages and message-history stats) */
115
+ onUsage?: (usage: ChatUsageData) => void;
92
116
  };
93
- declare function useChat({ api, threadId, agentId, agentVersion, agentExecutionId, dataContext, onError, onAuthError, onFinish, onData, onMessage, onUsage, }: UseChatConfig): {
117
+ declare function useChat({ api, threadId, agentId, agentVersion, agentExecutionId, dataContext, messagesToLoad, onError, onAuthError, onFinish, onData, onMessage, onUsage, }: UseChatConfig): {
94
118
  messages: ChatMessage[];
95
119
  status: ai.ChatStatus;
96
120
  isLoadingInitial: boolean;
@@ -121,6 +145,7 @@ declare function useChat({ api, threadId, agentId, agentVersion, agentExecutionI
121
145
  addToolApprovalResponse: ai.ChatAddToolApproveResponseFunction;
122
146
  pendingToolOutput: PendingToolOutput | null;
123
147
  pendingToolApproval: PendingToolApproval | null;
148
+ usage: ChatUsageData | null;
124
149
  };
125
150
 
126
151
  /** Matches POST /api/tools/:toolId/invoke request body */
@@ -414,6 +439,8 @@ interface ChatWidgetConfig extends UseChatConfig {
414
439
  widgets?: AnyUIWidgetDefinition[];
415
440
  /** Feedback options for assistant messages. Enabled by default. */
416
441
  feedback?: ChatWidgetFeedbackOptions;
442
+ /** Show a compact input/output token counter (from the server's usage data). Default: false. */
443
+ showTokenUsage?: boolean;
417
444
  }
418
445
  declare const ChatWidget: React.ForwardRefExoticComponent<ChatWidgetConfig & React.RefAttributes<ChatWidgetHandle>>;
419
446
 
@@ -642,4 +669,4 @@ declare const getVendorCardsWidget: (isProd?: boolean) => SDKUIWidgetDefinition[
642
669
 
643
670
  declare function cn(...inputs: ClassValue[]): string;
644
671
 
645
- export { type AgentVersion, type AnyUIWidgetDefinition, type ApiConfig, type ApprovalUIConfig, BriefDisplayMode, BriefDisplayMode as BriefRenderer, type ChatMessage, type ChatMessageSection, ChatWidget, type ChatWidgetFeedbackOptions, type ChatWidgetHandle, type ChatWidgetConfig as ChatWidgetProps, type ChatWidgetSpeechToTextOptions, type ChatWidgetStyles, type ChatWidgetVoiceOptions, type CustomerReactDOM, type DisplayMode, type DisplayModeProps, type EmbeddableChatWidgetConfig, type EnrichedResults, type FeedbackConfig, type FeedbackHandlers, type FetchApprovalConfigOptions, FullDisplayMode, FullDisplayMode as FullRenderer, HideToolsDisplayMode, HideToolsDisplayMode as HideToolsRenderer, type InvokeTool, type MessageContext, MessageRenderer, type MessageRendererProps, type PendingToolApproval, type PendingToolOutput, type PopupAnchorConfig, PopupChatWidget, type PopupChatWidgetProps, type DisplayModeProps as RendererProps, type SDKUIWidgetDefinition, SDK_WIDGET_MARKER, type StructuredMessagePayload, type SubmitFeedbackParams, TagGroupDisplay, type TagGroupDisplayProps, ToolCallDisplay, type ToolCallDisplayProps, type ToolInvokeRequest, type ToolInvokeResult, type ToolPart, type UIMessagePart, type UIWidgetDefinition, type UseChatConfig, type UseFeedbackConfig, type WidgetRenderOptions, cn, createSDKWidget, createWidget, defaultChatWidgets, fetchApprovalConfig, getVendorCardsWidget, isSDKWidget, registerChatWidgets, transformMessage, useChat, useFeedback };
672
+ export { type AgentVersion, type AnyUIWidgetDefinition, type ApiConfig, type ApprovalUIConfig, BriefDisplayMode, BriefDisplayMode as BriefRenderer, type ChatMessage, type ChatMessageSection, type ChatUsageData, ChatWidget, type ChatWidgetFeedbackOptions, type ChatWidgetHandle, type ChatWidgetConfig as ChatWidgetProps, type ChatWidgetSpeechToTextOptions, type ChatWidgetStyles, type ChatWidgetVoiceOptions, type CustomerReactDOM, type DisplayMode, type DisplayModeProps, type EmbeddableChatWidgetConfig, type EnrichedResults, type FeedbackConfig, type FeedbackHandlers, type FetchApprovalConfigOptions, FullDisplayMode, FullDisplayMode as FullRenderer, HideToolsDisplayMode, HideToolsDisplayMode as HideToolsRenderer, type InvokeTool, type MessageContext, MessageRenderer, type MessageRendererProps, type PendingToolApproval, type PendingToolOutput, type PopupAnchorConfig, PopupChatWidget, type PopupChatWidgetProps, type DisplayModeProps as RendererProps, type SDKUIWidgetDefinition, SDK_WIDGET_MARKER, type StructuredMessagePayload, type SubmitFeedbackParams, TagGroupDisplay, type TagGroupDisplayProps, ToolCallDisplay, type ToolCallDisplayProps, type ToolInvokeRequest, type ToolInvokeResult, type ToolPart, type UIMessagePart, type UIWidgetDefinition, type UseChatConfig, type UseFeedbackConfig, type WidgetRenderOptions, buildMessagesUrl, cn, createSDKWidget, createWidget, defaultChatWidgets, extractUsageData, fetchApprovalConfig, getVendorCardsWidget, isSDKWidget, registerChatWidgets, transformMessage, useChat, useFeedback };
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ function styleInject(css, { insertAt } = {}) {
21
21
  }
22
22
 
23
23
  // lib/chat/ChatWidget.css
24
- styleInject(':root[data-chat-widget],\n[data-chat-widget] {\n --chat-primary: #3b82f6;\n --chat-primary-text: #ffffff;\n --chat-primary-hover: #2563eb;\n --chat-primary-subtle: rgba(59, 130, 246, 0.1);\n --chat-background: #ffffff;\n --chat-background-secondary: #f9fafb;\n --chat-background-tertiary: #f3f4f6;\n --chat-border: #e5e7eb;\n --chat-border-light: #f3f4f6;\n --chat-widget-border-width: 1px;\n --chat-text: #111827;\n --chat-text-secondary: #4b5563;\n --chat-text-muted: #6b7280;\n --chat-text-disabled: #9ca3af;\n --chat-link: #2563eb;\n --chat-link-hover: #1d4ed8;\n --chat-success: #22c55e;\n --chat-success-bg: rgba(34, 197, 94, 0.1);\n --chat-error: #ef4444;\n --chat-error-bg: rgba(239, 68, 68, 0.1);\n --chat-header-text: #ffffff;\n --chat-user-text: #ffffff;\n --chat-assistant-bg: transparent;\n --chat-assistant-text: var(--chat-text);\n --chat-input-bg: var(--chat-background);\n --chat-input-text: var(--chat-text);\n --chat-input-placeholder: var(--chat-text-muted);\n --chat-thought-border: var(--chat-border);\n --chat-font-family:\n "Inter",\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n sans-serif;\n --chat-radius: 0.75rem;\n --chat-font-size: 0.925rem;\n --chat-thought-font-size: 0.75rem;\n --chat-shadow: 0 20px 45px rgba(0, 0, 0, 0.12);\n --chat-shadow-sm: 0 4px 12px rgba(0, 0, 0, 0.1);\n --chat-overlay-bg: rgba(0, 0, 0, 0.3);\n}\n.chat-widget {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 24rem;\n background: var(--chat-background);\n border: var(--chat-widget-border-width) solid var(--chat-border);\n border-radius: 0;\n box-shadow: var(--chat-shadow);\n overflow: hidden;\n font-family: var(--chat-font-family);\n color: var(--chat-assistant-text);\n}\n.chat-widget--popup-content {\n border: 0;\n border-radius: inherit;\n box-shadow: none;\n min-height: 0;\n}\n.chat-widget__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 40px;\n padding: 0.75rem 1rem;\n background: var(--chat-primary);\n color: var(--chat-header-text);\n}\n.chat-widget__title {\n margin: 0;\n font-size: 0.875rem;\n font-weight: 600;\n}\n.chat-widget__messages {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n min-width: 0;\n}\n.chat-widget__message {\n display: flex;\n flex-direction: column;\n gap: 0;\n min-width: 0;\n}\n.chat-widget__message-row {\n display: flex;\n min-width: 0;\n}\n.chat-widget__message-row--user {\n justify-content: flex-end;\n}\n.chat-widget__message-row--assistant {\n justify-content: flex-start;\n}\n.chat-widget__bubble {\n max-width: 90%;\n padding: 0.5rem 0.25rem;\n border-radius: calc(var(--chat-radius) * 0.65);\n font-size: var(--chat-font-size);\n min-width: 0;\n overflow-x: hidden;\n}\n.chat-widget__bubble--user {\n background: var(--chat-primary);\n color: var(--chat-user-text);\n border-bottom-right-radius: 0.35rem;\n padding-left: 0.375rem;\n padding-right: 0.375rem;\n}\n.chat-widget__bubble--assistant {\n width: 90%;\n max-width: 90%;\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n border-bottom-left-radius: 0.35rem;\n}\n.chat-widget__widget {\n width: 100%;\n max-width: 100%;\n min-width: 0;\n overflow-x: hidden;\n}\n.widget-customer-root {\n width: 100%;\n max-width: 100%;\n min-width: 0;\n overflow-x: hidden;\n}\n.chat-widget__markdown {\n white-space: normal;\n font-size: var(--chat-font-size);\n}\n.chat-widget__markdown h1 {\n font-size: calc(var(--chat-font-size) * 1.4);\n}\n.chat-widget__markdown h2 {\n font-size: calc(var(--chat-font-size) * 1.25);\n}\n.chat-widget__markdown h3 {\n font-size: calc(var(--chat-font-size) * 1.1);\n}\n.chat-widget__markdown h4 {\n font-size: calc(var(--chat-font-size) * 1.05);\n}\n.chat-widget__markdown h5 {\n font-size: calc(var(--chat-font-size) * 1);\n}\n.chat-widget__markdown h6 {\n font-size: calc(var(--chat-font-size) * 0.95);\n}\n.chat-widget__anchor-button {\n position: fixed;\n bottom: 20px;\n right: 20px;\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.65rem 0.85rem;\n background: var(--chat-primary);\n color: var(--chat-primary-text);\n border: none;\n border-radius: 999px;\n box-shadow: var(--chat-shadow);\n cursor: pointer;\n font-weight: 600;\n z-index: 99999;\n}\n.chat-widget__anchor-button:hover {\n background: var(--chat-primary-hover);\n}\n.chat-widget__anchor--left {\n right: auto;\n left: 20px;\n}\n.chat-widget__anchor-icon {\n width: 1.1rem;\n height: 1.1rem;\n}\n.chat-widget__popup {\n position: fixed;\n bottom: 80px;\n right: 20px;\n z-index: 99998;\n}\n.chat-widget__anchor--left.chat-widget__popup {\n right: auto;\n left: 20px;\n}\n.chat-widget__popup-inner {\n width: 384px;\n max-width: calc(100vw - 40px);\n height: 500px;\n max-height: calc(100vh - 140px);\n box-shadow: var(--chat-shadow);\n border-radius: 12px;\n overflow: hidden;\n}\n.chat-widget__markdown a {\n color: var(--chat-link);\n text-decoration: underline;\n}\n.chat-widget__markdown a:hover {\n color: var(--chat-link-hover);\n}\n.chat-widget__markdown table {\n width: 100%;\n border-collapse: collapse;\n margin: 0.5rem 0;\n}\n.chat-widget__markdown th,\n.chat-widget__markdown td {\n border: 1px solid var(--chat-border);\n padding: 0.5rem;\n text-align: left;\n vertical-align: top;\n}\n.chat-widget__markdown thead th {\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n font-weight: 600;\n}\n.chat-widget__thoughts {\n min-width: 0;\n --chat-font-size: var(--chat-thought-font-size);\n}\n.chat-widget__details {\n border: 0;\n}\n.chat-widget__thoughts-summary {\n list-style: none;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n cursor: pointer;\n color: var(--chat-text-muted);\n font-size: 0.8125rem;\n}\n.chat-widget__thoughts-summary:hover {\n color: var(--chat-assistant-text);\n}\n.chat-widget__thoughts-icon-container {\n display: flex;\n border: 1px solid var(--chat-border);\n border-radius: 999px;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__thoughts-icon {\n width: 0.75rem;\n height: 0.75rem;\n transition: transform 0.2s ease;\n}\n.chat-widget__details[open] .chat-widget__thoughts-icon {\n transform: rotate(90deg);\n}\n.chat-widget__thoughts-content {\n margin-top: 0.5rem;\n margin-left: 0.4rem;\n padding: 0.75rem;\n border-left: 2px solid var(--chat-thought-border);\n border-color: var(--chat-primary);\n max-width: 100%;\n overflow-x: auto;\n}\n.chat-widget__thoughts-text {\n margin: 0;\n line-height: 1.5;\n color: var(--chat-text-secondary);\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n "Liberation Mono",\n "Courier New",\n monospace;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-wrap: anywhere;\n display: block;\n}\n.chat-widget__loading {\n display: flex;\n justify-content: flex-start;\n}\n.chat-widget__loading-bubble {\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n border-radius: calc(var(--chat-radius) * 0.65);\n border-bottom-left-radius: 0.35rem;\n padding: 0.5rem 0.75rem;\n}\n.chat-widget__loading-dots {\n display: flex;\n gap: 0.35rem;\n}\n.chat-widget__loading-dot {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 999px;\n background: var(--chat-text-disabled);\n animation: chat-widget-bounce 1s infinite ease-in-out;\n}\n.chat-widget__loading-dot[data-delay="1"] {\n animation-delay: 0.1s;\n}\n.chat-widget__loading-dot[data-delay="2"] {\n animation-delay: 0.2s;\n}\n@keyframes chat-widget-bounce {\n 0%, 80%, 100% {\n transform: scale(0.6);\n opacity: 0.4;\n }\n 40% {\n transform: scale(1);\n opacity: 1;\n }\n}\n.chat-widget__input {\n border-top: 1px solid var(--chat-border);\n padding: 0.25rem 0 0.75rem;\n background: var(--chat-input-bg);\n}\n.chat-widget__form {\n position: relative;\n}\n.chat-widget__textarea {\n width: 100%;\n border: 0;\n padding: 0.75rem 5.25rem 0.75rem 0.75rem;\n background: transparent;\n font-size: 0.925rem;\n resize: none;\n color: var(--chat-input-text);\n font-family: inherit;\n}\n.chat-widget__textarea::-moz-placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__textarea::placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__textarea:focus-visible {\n outline: none;\n}\n.chat-widget__textarea:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.chat-widget__toolbar {\n position: absolute;\n top: 0;\n right: 3.75rem;\n height: 100%;\n display: flex;\n align-items: center;\n padding: 0 0.5rem;\n border-right: 1px solid var(--chat-border);\n}\n.chat-widget__submit {\n position: absolute;\n top: 50%;\n right: 0.75rem;\n transform: translateY(-50%);\n background: transparent;\n border: 0;\n width: 2.5rem;\n height: 2.5rem;\n display: grid;\n place-items: center;\n color: var(--chat-primary);\n cursor: pointer;\n}\n.chat-widget__submit:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__submit:not(:disabled):hover {\n color: var(--chat-primary-hover);\n}\n.chat-widget__send-icon {\n width: 1.2rem;\n height: 1.2rem;\n}\n.chat-widget__mic-button {\n position: relative;\n border: none;\n background: transparent;\n width: 2.25rem;\n height: 2.25rem;\n display: grid;\n place-items: center;\n color: var(--chat-primary);\n cursor: pointer;\n border-radius: 999px;\n}\n.chat-widget__mic-button:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__mic-button--active {\n color: var(--chat-primary-hover);\n background: var(--chat-primary-subtle);\n}\n.chat-widget__mic-icon {\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__mic-bar {\n position: absolute;\n bottom: 0.1rem;\n left: 50%;\n width: 16px;\n height: 2px;\n border-radius: 999px;\n background: var(--chat-border);\n overflow: hidden;\n display: block;\n transform: translateX(-50%);\n pointer-events: none;\n}\n.chat-widget__mic-bar-fill {\n display: block;\n width: 100%;\n height: 100%;\n background: currentColor;\n transform-origin: left;\n transition: transform 0.12s linear;\n}\n.chat-widget__voice {\n display: flex;\n margin-top: 0.25rem;\n}\n.chat-widget__voice-button {\n border: none;\n background: none;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.1rem 0;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--chat-primary);\n cursor: pointer;\n}\n.chat-widget__voice-button:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__voice-button--active {\n color: var(--chat-primary-hover);\n}\n.chat-widget__voice-icon {\n width: 0.95rem;\n height: 0.95rem;\n}\n.chat-widget__voice-icon--spin {\n animation: chat-widget-spin 1s linear infinite;\n}\n@keyframes chat-widget-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.chat-widget__collapsed {\n position: relative;\n margin-bottom: 0.25rem;\n}\n.chat-widget__collapsed-content {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 300ms ease-out;\n}\n.chat-widget__collapsed-content--expanded {\n grid-template-rows: 1fr;\n}\n.chat-widget__collapsed-content-inner {\n overflow: hidden;\n}\n.chat-widget__collapsed-preview {\n position: relative;\n max-height: 1.5em;\n overflow: hidden;\n opacity: 0.6;\n pointer-events: none;\n transition: opacity 300ms ease-out, max-height 300ms ease-out;\n}\n.chat-widget__collapsed-preview--hidden {\n opacity: 0;\n max-height: 0;\n pointer-events: none;\n}\n.chat-widget__collapsed-gradient {\n position: absolute;\n top: 0;\n right: 0;\n width: 70%;\n height: 100%;\n background:\n linear-gradient(\n to right,\n transparent 0%,\n var(--chat-background) 90%);\n pointer-events: none;\n}\n.chat-widget__collapsed-toggle {\n display: inline-block;\n padding: 0;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--chat-primary);\n background: transparent;\n border: none;\n cursor: pointer;\n}\n.chat-widget__collapsed-toggle:hover {\n text-decoration: underline;\n}\n@keyframes chat-widget-slide-up {\n from {\n opacity: 1;\n transform: translateY(0);\n max-height: 200px;\n }\n to {\n opacity: 0.6;\n transform: translateY(-8px);\n max-height: 1.5em;\n }\n}\n.chat-widget__collapsed--animating .chat-widget__collapsed-preview {\n animation: chat-widget-slide-up 300ms ease-out forwards;\n}\n');
24
+ styleInject(':root[data-chat-widget],\n[data-chat-widget] {\n --chat-primary: #3b82f6;\n --chat-primary-text: #ffffff;\n --chat-primary-hover: #2563eb;\n --chat-primary-subtle: rgba(59, 130, 246, 0.1);\n --chat-background: #ffffff;\n --chat-background-secondary: #f9fafb;\n --chat-background-tertiary: #f3f4f6;\n --chat-border: #e5e7eb;\n --chat-border-light: #f3f4f6;\n --chat-widget-border-width: 1px;\n --chat-text: #111827;\n --chat-text-secondary: #4b5563;\n --chat-text-muted: #6b7280;\n --chat-text-disabled: #9ca3af;\n --chat-link: #2563eb;\n --chat-link-hover: #1d4ed8;\n --chat-success: #22c55e;\n --chat-success-bg: rgba(34, 197, 94, 0.1);\n --chat-error: #ef4444;\n --chat-error-bg: rgba(239, 68, 68, 0.1);\n --chat-header-text: #ffffff;\n --chat-user-text: #ffffff;\n --chat-assistant-bg: transparent;\n --chat-assistant-text: var(--chat-text);\n --chat-input-bg: var(--chat-background);\n --chat-input-text: var(--chat-text);\n --chat-input-placeholder: var(--chat-text-muted);\n --chat-thought-border: var(--chat-border);\n --chat-font-family:\n "Inter",\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n sans-serif;\n --chat-radius: 0.75rem;\n --chat-font-size: 0.925rem;\n --chat-thought-font-size: 0.75rem;\n --chat-shadow: 0 20px 45px rgba(0, 0, 0, 0.12);\n --chat-shadow-sm: 0 4px 12px rgba(0, 0, 0, 0.1);\n --chat-overlay-bg: rgba(0, 0, 0, 0.3);\n}\n.chat-widget {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 24rem;\n background: var(--chat-background);\n border: var(--chat-widget-border-width) solid var(--chat-border);\n border-radius: 0;\n box-shadow: var(--chat-shadow);\n overflow: hidden;\n font-family: var(--chat-font-family);\n color: var(--chat-assistant-text);\n}\n.chat-widget--popup-content {\n border: 0;\n border-radius: inherit;\n box-shadow: none;\n min-height: 0;\n}\n.chat-widget__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 40px;\n padding: 0.75rem 1rem;\n background: var(--chat-primary);\n color: var(--chat-header-text);\n}\n.chat-widget__title {\n margin: 0;\n font-size: 0.875rem;\n font-weight: 600;\n}\n.chat-widget__messages {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 1rem;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n min-width: 0;\n}\n.chat-widget__message {\n display: flex;\n flex-direction: column;\n gap: 0;\n min-width: 0;\n}\n.chat-widget__message-row {\n display: flex;\n min-width: 0;\n}\n.chat-widget__message-row--user {\n justify-content: flex-end;\n}\n.chat-widget__message-row--assistant {\n justify-content: flex-start;\n}\n.chat-widget__bubble {\n max-width: 90%;\n padding: 0.5rem 0.25rem;\n border-radius: calc(var(--chat-radius) * 0.65);\n font-size: var(--chat-font-size);\n min-width: 0;\n overflow-x: hidden;\n}\n.chat-widget__bubble--user {\n background: var(--chat-primary);\n color: var(--chat-user-text);\n border-bottom-right-radius: 0.35rem;\n padding-left: 0.375rem;\n padding-right: 0.375rem;\n}\n.chat-widget__bubble--assistant {\n width: 90%;\n max-width: 90%;\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n border-bottom-left-radius: 0.35rem;\n}\n.chat-widget__widget {\n width: 100%;\n max-width: 100%;\n min-width: 0;\n overflow-x: hidden;\n}\n.widget-customer-root {\n width: 100%;\n max-width: 100%;\n min-width: 0;\n overflow-x: hidden;\n}\n.chat-widget__markdown {\n white-space: normal;\n font-size: var(--chat-font-size);\n}\n.chat-widget__markdown h1 {\n font-size: calc(var(--chat-font-size) * 1.4);\n}\n.chat-widget__markdown h2 {\n font-size: calc(var(--chat-font-size) * 1.25);\n}\n.chat-widget__markdown h3 {\n font-size: calc(var(--chat-font-size) * 1.1);\n}\n.chat-widget__markdown h4 {\n font-size: calc(var(--chat-font-size) * 1.05);\n}\n.chat-widget__markdown h5 {\n font-size: calc(var(--chat-font-size) * 1);\n}\n.chat-widget__markdown h6 {\n font-size: calc(var(--chat-font-size) * 0.95);\n}\n.chat-widget__anchor-button {\n position: fixed;\n bottom: 20px;\n right: 20px;\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.65rem 0.85rem;\n background: var(--chat-primary);\n color: var(--chat-primary-text);\n border: none;\n border-radius: 999px;\n box-shadow: var(--chat-shadow);\n cursor: pointer;\n font-weight: 600;\n z-index: 99999;\n}\n.chat-widget__anchor-button:hover {\n background: var(--chat-primary-hover);\n}\n.chat-widget__anchor--left {\n right: auto;\n left: 20px;\n}\n.chat-widget__anchor-icon {\n width: 1.1rem;\n height: 1.1rem;\n}\n.chat-widget__popup {\n position: fixed;\n bottom: 80px;\n right: 20px;\n z-index: 99998;\n}\n.chat-widget__anchor--left.chat-widget__popup {\n right: auto;\n left: 20px;\n}\n.chat-widget__popup-inner {\n width: 384px;\n max-width: calc(100vw - 40px);\n height: 500px;\n max-height: calc(100vh - 140px);\n box-shadow: var(--chat-shadow);\n border-radius: 12px;\n overflow: hidden;\n}\n.chat-widget__markdown a {\n color: var(--chat-link);\n text-decoration: underline;\n}\n.chat-widget__markdown a:hover {\n color: var(--chat-link-hover);\n}\n.chat-widget__markdown table {\n width: 100%;\n border-collapse: collapse;\n margin: 0.5rem 0;\n}\n.chat-widget__markdown th,\n.chat-widget__markdown td {\n border: 1px solid var(--chat-border);\n padding: 0.5rem;\n text-align: left;\n vertical-align: top;\n}\n.chat-widget__markdown thead th {\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n font-weight: 600;\n}\n.chat-widget__thoughts {\n min-width: 0;\n --chat-font-size: var(--chat-thought-font-size);\n}\n.chat-widget__details {\n border: 0;\n}\n.chat-widget__thoughts-summary {\n list-style: none;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n cursor: pointer;\n color: var(--chat-text-muted);\n font-size: 0.8125rem;\n}\n.chat-widget__thoughts-summary:hover {\n color: var(--chat-assistant-text);\n}\n.chat-widget__thoughts-icon-container {\n display: flex;\n border: 1px solid var(--chat-border);\n border-radius: 999px;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__thoughts-icon {\n width: 0.75rem;\n height: 0.75rem;\n transition: transform 0.2s ease;\n}\n.chat-widget__details[open] .chat-widget__thoughts-icon {\n transform: rotate(90deg);\n}\n.chat-widget__thoughts-content {\n margin-top: 0.5rem;\n margin-left: 0.4rem;\n padding: 0.75rem;\n border-left: 2px solid var(--chat-thought-border);\n border-color: var(--chat-primary);\n max-width: 100%;\n overflow-x: auto;\n}\n.chat-widget__thoughts-text {\n margin: 0;\n line-height: 1.5;\n color: var(--chat-text-secondary);\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n "Liberation Mono",\n "Courier New",\n monospace;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-wrap: anywhere;\n display: block;\n}\n.chat-widget__loading {\n display: flex;\n justify-content: flex-start;\n}\n.chat-widget__loading-bubble {\n background: var(--chat-assistant-bg);\n color: var(--chat-assistant-text);\n border-radius: calc(var(--chat-radius) * 0.65);\n border-bottom-left-radius: 0.35rem;\n padding: 0.5rem 0.75rem;\n}\n.chat-widget__loading-dots {\n display: flex;\n gap: 0.35rem;\n}\n.chat-widget__loading-dot {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 999px;\n background: var(--chat-text-disabled);\n animation: chat-widget-bounce 1s infinite ease-in-out;\n}\n.chat-widget__loading-dot[data-delay="1"] {\n animation-delay: 0.1s;\n}\n.chat-widget__loading-dot[data-delay="2"] {\n animation-delay: 0.2s;\n}\n@keyframes chat-widget-bounce {\n 0%, 80%, 100% {\n transform: scale(0.6);\n opacity: 0.4;\n }\n 40% {\n transform: scale(1);\n opacity: 1;\n }\n}\n.chat-widget__token-usage {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 0.25rem 0.25rem 0;\n font-size: 0.6875rem;\n line-height: 1.2;\n color: var(--chat-text-muted);\n}\n.chat-widget__token-usage-item {\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n.chat-widget__input {\n border-top: 1px solid var(--chat-border);\n padding: 0.25rem 0 0.75rem;\n background: var(--chat-input-bg);\n}\n.chat-widget__form {\n position: relative;\n}\n.chat-widget__textarea {\n width: 100%;\n border: 0;\n padding: 0.75rem 5.25rem 0.75rem 0.75rem;\n background: transparent;\n font-size: 0.925rem;\n resize: none;\n color: var(--chat-input-text);\n font-family: inherit;\n}\n.chat-widget__textarea::-moz-placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__textarea::placeholder {\n color: var(--chat-input-placeholder);\n}\n.chat-widget__textarea:focus-visible {\n outline: none;\n}\n.chat-widget__textarea:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.chat-widget__toolbar {\n position: absolute;\n top: 0;\n right: 3.75rem;\n height: 100%;\n display: flex;\n align-items: center;\n padding: 0 0.5rem;\n border-right: 1px solid var(--chat-border);\n}\n.chat-widget__submit {\n position: absolute;\n top: 50%;\n right: 0.75rem;\n transform: translateY(-50%);\n background: transparent;\n border: 0;\n width: 2.5rem;\n height: 2.5rem;\n display: grid;\n place-items: center;\n color: var(--chat-primary);\n cursor: pointer;\n}\n.chat-widget__submit:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__submit:not(:disabled):hover {\n color: var(--chat-primary-hover);\n}\n.chat-widget__send-icon {\n width: 1.2rem;\n height: 1.2rem;\n}\n.chat-widget__mic-button {\n position: relative;\n border: none;\n background: transparent;\n width: 2.25rem;\n height: 2.25rem;\n display: grid;\n place-items: center;\n color: var(--chat-primary);\n cursor: pointer;\n border-radius: 999px;\n}\n.chat-widget__mic-button:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__mic-button--active {\n color: var(--chat-primary-hover);\n background: var(--chat-primary-subtle);\n}\n.chat-widget__mic-icon {\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__mic-bar {\n position: absolute;\n bottom: 0.1rem;\n left: 50%;\n width: 16px;\n height: 2px;\n border-radius: 999px;\n background: var(--chat-border);\n overflow: hidden;\n display: block;\n transform: translateX(-50%);\n pointer-events: none;\n}\n.chat-widget__mic-bar-fill {\n display: block;\n width: 100%;\n height: 100%;\n background: currentColor;\n transform-origin: left;\n transition: transform 0.12s linear;\n}\n.chat-widget__voice {\n display: flex;\n margin-top: 0.25rem;\n}\n.chat-widget__voice-button {\n border: none;\n background: none;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.1rem 0;\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--chat-primary);\n cursor: pointer;\n}\n.chat-widget__voice-button:disabled {\n color: var(--chat-text-disabled);\n cursor: not-allowed;\n}\n.chat-widget__voice-button--active {\n color: var(--chat-primary-hover);\n}\n.chat-widget__voice-icon {\n width: 0.95rem;\n height: 0.95rem;\n}\n.chat-widget__voice-icon--spin {\n animation: chat-widget-spin 1s linear infinite;\n}\n@keyframes chat-widget-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.chat-widget__collapsed {\n position: relative;\n margin-bottom: 0.25rem;\n}\n.chat-widget__collapsed-content {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 300ms ease-out;\n}\n.chat-widget__collapsed-content--expanded {\n grid-template-rows: 1fr;\n}\n.chat-widget__collapsed-content-inner {\n overflow: hidden;\n}\n.chat-widget__collapsed-preview {\n position: relative;\n max-height: 1.5em;\n overflow: hidden;\n opacity: 0.6;\n pointer-events: none;\n transition: opacity 300ms ease-out, max-height 300ms ease-out;\n}\n.chat-widget__collapsed-preview--hidden {\n opacity: 0;\n max-height: 0;\n pointer-events: none;\n}\n.chat-widget__collapsed-gradient {\n position: absolute;\n top: 0;\n right: 0;\n width: 70%;\n height: 100%;\n background:\n linear-gradient(\n to right,\n transparent 0%,\n var(--chat-background) 90%);\n pointer-events: none;\n}\n.chat-widget__collapsed-toggle {\n display: inline-block;\n padding: 0;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--chat-primary);\n background: transparent;\n border: none;\n cursor: pointer;\n}\n.chat-widget__collapsed-toggle:hover {\n text-decoration: underline;\n}\n@keyframes chat-widget-slide-up {\n from {\n opacity: 1;\n transform: translateY(0);\n max-height: 200px;\n }\n to {\n opacity: 0.6;\n transform: translateY(-8px);\n max-height: 1.5em;\n }\n}\n.chat-widget__collapsed--animating .chat-widget__collapsed-preview {\n animation: chat-widget-slide-up 300ms ease-out forwards;\n}\n');
25
25
 
26
26
  // lib/chat/ChatWidget.tsx
27
27
  import { Send, StopCircle } from "lucide-react";
@@ -4217,6 +4217,22 @@ function createAuthAwareFetch(tokenRef, onAuthError) {
4217
4217
  return response;
4218
4218
  };
4219
4219
  }
4220
+ function extractUsageData(dataPart) {
4221
+ if (dataPart && typeof dataPart === "object") {
4222
+ const part = dataPart;
4223
+ if (part.type === "data-usage" && part.data) {
4224
+ return part.data;
4225
+ }
4226
+ }
4227
+ return null;
4228
+ }
4229
+ function buildMessagesUrl(baseUrl, messagesToLoad) {
4230
+ const base = `${baseUrl}/chat/messages`;
4231
+ if (messagesToLoad != null && Number.isFinite(messagesToLoad) && messagesToLoad > 0) {
4232
+ return `${base}?limit=${messagesToLoad}`;
4233
+ }
4234
+ return base;
4235
+ }
4220
4236
  var EMPTY_HEADERS = {};
4221
4237
  function useChat({
4222
4238
  api,
@@ -4225,6 +4241,7 @@ function useChat({
4225
4241
  agentVersion,
4226
4242
  agentExecutionId,
4227
4243
  dataContext,
4244
+ messagesToLoad,
4228
4245
  onError,
4229
4246
  onAuthError,
4230
4247
  onFinish,
@@ -4295,11 +4312,10 @@ function useChat({
4295
4312
  },
4296
4313
  onData: (dataPart) => {
4297
4314
  onData?.(dataPart);
4298
- if (dataPart && typeof dataPart === "object") {
4299
- const part = dataPart;
4300
- if (part.type === "data-usage" && part.data) {
4301
- onUsage?.(part.data);
4302
- }
4315
+ const usageData = extractUsageData(dataPart);
4316
+ if (usageData) {
4317
+ setUsage(usageData);
4318
+ onUsage?.(usageData);
4303
4319
  }
4304
4320
  }
4305
4321
  });
@@ -4320,6 +4336,7 @@ function useChat({
4320
4336
  [sendMessage]
4321
4337
  );
4322
4338
  const [isLoadingInitial, setIsLoadingInitial] = useState(true);
4339
+ const [usage, setUsage] = useState(null);
4323
4340
  const hasFetchedRef = useRef(false);
4324
4341
  useEffect(() => {
4325
4342
  hasFetchedRef.current = false;
@@ -4329,7 +4346,7 @@ function useChat({
4329
4346
  const fetchInitialMessages = async () => {
4330
4347
  hasFetchedRef.current = true;
4331
4348
  try {
4332
- const response = await authFetch(`${baseUrl}/chat/messages`, {
4349
+ const response = await authFetch(buildMessagesUrl(baseUrl, messagesToLoad), {
4333
4350
  method: "GET",
4334
4351
  headers: {
4335
4352
  "thread-id": threadId,
@@ -4353,7 +4370,7 @@ function useChat({
4353
4370
  }
4354
4371
  };
4355
4372
  fetchInitialMessages();
4356
- }, [agentExecutionId, agentId, authFetch, baseUrl, customHeadersKey, threadId]);
4373
+ }, [agentExecutionId, agentId, authFetch, baseUrl, customHeadersKey, threadId, messagesToLoad]);
4357
4374
  useEffect(() => {
4358
4375
  if (!onMessage || messages.length === 0) return;
4359
4376
  const lastMessage = messages[messages.length - 1];
@@ -4416,7 +4433,8 @@ function useChat({
4416
4433
  addToolOutput,
4417
4434
  addToolApprovalResponse,
4418
4435
  pendingToolOutput,
4419
- pendingToolApproval
4436
+ pendingToolApproval,
4437
+ usage
4420
4438
  };
4421
4439
  }
4422
4440
 
@@ -9594,6 +9612,8 @@ var classNames2 = {
9594
9612
  header: "chat-widget__header",
9595
9613
  headerTitle: "chat-widget__title",
9596
9614
  messagesContainer: "chat-widget__messages",
9615
+ tokenUsage: "chat-widget__token-usage",
9616
+ tokenUsageItem: "chat-widget__token-usage-item",
9597
9617
  messageWrapper: "chat-widget__message",
9598
9618
  messageRow: "chat-widget__message-row",
9599
9619
  userMessageRow: "chat-widget__message-row--user",
@@ -9713,11 +9733,14 @@ var ChatWidget = forwardRef(function ChatWidget2({
9713
9733
  agentVersion,
9714
9734
  agentExecutionId,
9715
9735
  dataContext,
9736
+ messagesToLoad,
9716
9737
  displayMode = "brief",
9717
9738
  onError,
9718
9739
  onAuthError,
9719
9740
  onFinish,
9720
9741
  onMessage,
9742
+ onUsage,
9743
+ onData,
9721
9744
  title,
9722
9745
  initialAssistantMessage,
9723
9746
  initialUserMessage,
@@ -9727,7 +9750,8 @@ var ChatWidget = forwardRef(function ChatWidget2({
9727
9750
  voice,
9728
9751
  speechToText,
9729
9752
  widgets,
9730
- feedback
9753
+ feedback,
9754
+ showTokenUsage = false
9731
9755
  }, ref) {
9732
9756
  const [detectedDarkMode, setDetectedDarkMode] = useState9(() => detectChatWidgetDarkMode());
9733
9757
  useEffect6(() => {
@@ -9809,7 +9833,8 @@ var ChatWidget = forwardRef(function ChatWidget2({
9809
9833
  addToolOutput,
9810
9834
  addToolApprovalResponse,
9811
9835
  pendingToolOutput,
9812
- pendingToolApproval
9836
+ pendingToolApproval,
9837
+ usage
9813
9838
  } = useChat({
9814
9839
  api,
9815
9840
  threadId,
@@ -9817,10 +9842,13 @@ var ChatWidget = forwardRef(function ChatWidget2({
9817
9842
  agentVersion,
9818
9843
  agentExecutionId: agentExecutionId ?? void 0,
9819
9844
  dataContext,
9845
+ messagesToLoad,
9820
9846
  onError,
9821
9847
  onAuthError,
9822
9848
  onFinish,
9823
- onMessage
9849
+ onMessage,
9850
+ onUsage,
9851
+ onData
9824
9852
  });
9825
9853
  const handleToolOutput = useCallback7((result) => {
9826
9854
  if (pendingToolOutput && addToolOutput) {
@@ -10121,6 +10149,18 @@ var ChatWidget = forwardRef(function ChatWidget2({
10121
10149
  ]
10122
10150
  }
10123
10151
  ),
10152
+ showTokenUsage && usage && /* @__PURE__ */ jsxs15("div", { className: classNames2.tokenUsage, "aria-label": "Token usage", children: [
10153
+ /* @__PURE__ */ jsxs15("span", { className: classNames2.tokenUsageItem, title: "Input tokens", children: [
10154
+ "\u2191 ",
10155
+ usage.inputTokens.toLocaleString(),
10156
+ " in"
10157
+ ] }),
10158
+ /* @__PURE__ */ jsxs15("span", { className: classNames2.tokenUsageItem, title: "Output tokens", children: [
10159
+ "\u2193 ",
10160
+ usage.outputTokens.toLocaleString(),
10161
+ " out"
10162
+ ] })
10163
+ ] }),
10124
10164
  /* @__PURE__ */ jsx18("div", { className: classNames2.inputContainer, children: /* @__PURE__ */ jsxs15("form", { onSubmit: handleSubmit, className: classNames2.inputForm, children: [
10125
10165
  /* @__PURE__ */ jsx18(
10126
10166
  "textarea",
@@ -10928,10 +10968,12 @@ export {
10928
10968
  SDK_WIDGET_MARKER,
10929
10969
  TagGroupDisplay,
10930
10970
  ToolCallDisplay,
10971
+ buildMessagesUrl,
10931
10972
  cn,
10932
10973
  createSDKWidget,
10933
10974
  createWidget,
10934
10975
  defaultChatWidgets,
10976
+ extractUsageData,
10935
10977
  fetchApprovalConfig,
10936
10978
  getVendorCardsWidget,
10937
10979
  isSDKWidget,