@ensembleapp/client-sdk 0.0.54 → 0.0.55
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 +79 -2
- package/dist/index.d.ts +29 -10
- package/dist/index.js +41 -10
- package/dist/index.js.map +1 -1
- package/dist/widget/widget.global.js +51 -51
- package/dist/widget/widget.global.js.map +1 -1
- package/lib/chat/ChatWidget.css +15 -0
- package/package.json +15 -15
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
|
-
|
|
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,29 @@ 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;
|
|
66
89
|
type UseChatConfig = DeprecatedChatConfig & {
|
|
67
90
|
/** The server API configuration */
|
|
68
91
|
api: ApiConfig;
|
|
@@ -80,15 +103,8 @@ type UseChatConfig = DeprecatedChatConfig & {
|
|
|
80
103
|
onFinish?: (message: any) => void;
|
|
81
104
|
onData?: (data: any) => void;
|
|
82
105
|
onMessage?: (message: UIMessage) => void;
|
|
83
|
-
/** Called when usage data is received (
|
|
84
|
-
onUsage?: (usage:
|
|
85
|
-
inputTokens: number;
|
|
86
|
-
outputTokens: number;
|
|
87
|
-
maxInputTokens?: number;
|
|
88
|
-
maxOutputTokens?: number;
|
|
89
|
-
inputTokensPercent?: number;
|
|
90
|
-
outputTokensPercent?: number;
|
|
91
|
-
}) => void;
|
|
106
|
+
/** Called when usage data is received (token counts/percentages and message-history stats) */
|
|
107
|
+
onUsage?: (usage: ChatUsageData) => void;
|
|
92
108
|
};
|
|
93
109
|
declare function useChat({ api, threadId, agentId, agentVersion, agentExecutionId, dataContext, onError, onAuthError, onFinish, onData, onMessage, onUsage, }: UseChatConfig): {
|
|
94
110
|
messages: ChatMessage[];
|
|
@@ -121,6 +137,7 @@ declare function useChat({ api, threadId, agentId, agentVersion, agentExecutionI
|
|
|
121
137
|
addToolApprovalResponse: ai.ChatAddToolApproveResponseFunction;
|
|
122
138
|
pendingToolOutput: PendingToolOutput | null;
|
|
123
139
|
pendingToolApproval: PendingToolApproval | null;
|
|
140
|
+
usage: ChatUsageData | null;
|
|
124
141
|
};
|
|
125
142
|
|
|
126
143
|
/** Matches POST /api/tools/:toolId/invoke request body */
|
|
@@ -414,6 +431,8 @@ interface ChatWidgetConfig extends UseChatConfig {
|
|
|
414
431
|
widgets?: AnyUIWidgetDefinition[];
|
|
415
432
|
/** Feedback options for assistant messages. Enabled by default. */
|
|
416
433
|
feedback?: ChatWidgetFeedbackOptions;
|
|
434
|
+
/** Show a compact input/output token counter (from the server's usage data). Default: false. */
|
|
435
|
+
showTokenUsage?: boolean;
|
|
417
436
|
}
|
|
418
437
|
declare const ChatWidget: React.ForwardRefExoticComponent<ChatWidgetConfig & React.RefAttributes<ChatWidgetHandle>>;
|
|
419
438
|
|
|
@@ -642,4 +661,4 @@ declare const getVendorCardsWidget: (isProd?: boolean) => SDKUIWidgetDefinition[
|
|
|
642
661
|
|
|
643
662
|
declare function cn(...inputs: ClassValue[]): string;
|
|
644
663
|
|
|
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 };
|
|
664
|
+
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, 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,15 @@ 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
|
+
}
|
|
4220
4229
|
var EMPTY_HEADERS = {};
|
|
4221
4230
|
function useChat({
|
|
4222
4231
|
api,
|
|
@@ -4295,11 +4304,10 @@ function useChat({
|
|
|
4295
4304
|
},
|
|
4296
4305
|
onData: (dataPart) => {
|
|
4297
4306
|
onData?.(dataPart);
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
}
|
|
4307
|
+
const usageData = extractUsageData(dataPart);
|
|
4308
|
+
if (usageData) {
|
|
4309
|
+
setUsage(usageData);
|
|
4310
|
+
onUsage?.(usageData);
|
|
4303
4311
|
}
|
|
4304
4312
|
}
|
|
4305
4313
|
});
|
|
@@ -4320,6 +4328,7 @@ function useChat({
|
|
|
4320
4328
|
[sendMessage]
|
|
4321
4329
|
);
|
|
4322
4330
|
const [isLoadingInitial, setIsLoadingInitial] = useState(true);
|
|
4331
|
+
const [usage, setUsage] = useState(null);
|
|
4323
4332
|
const hasFetchedRef = useRef(false);
|
|
4324
4333
|
useEffect(() => {
|
|
4325
4334
|
hasFetchedRef.current = false;
|
|
@@ -4416,7 +4425,8 @@ function useChat({
|
|
|
4416
4425
|
addToolOutput,
|
|
4417
4426
|
addToolApprovalResponse,
|
|
4418
4427
|
pendingToolOutput,
|
|
4419
|
-
pendingToolApproval
|
|
4428
|
+
pendingToolApproval,
|
|
4429
|
+
usage
|
|
4420
4430
|
};
|
|
4421
4431
|
}
|
|
4422
4432
|
|
|
@@ -9594,6 +9604,8 @@ var classNames2 = {
|
|
|
9594
9604
|
header: "chat-widget__header",
|
|
9595
9605
|
headerTitle: "chat-widget__title",
|
|
9596
9606
|
messagesContainer: "chat-widget__messages",
|
|
9607
|
+
tokenUsage: "chat-widget__token-usage",
|
|
9608
|
+
tokenUsageItem: "chat-widget__token-usage-item",
|
|
9597
9609
|
messageWrapper: "chat-widget__message",
|
|
9598
9610
|
messageRow: "chat-widget__message-row",
|
|
9599
9611
|
userMessageRow: "chat-widget__message-row--user",
|
|
@@ -9718,6 +9730,8 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
9718
9730
|
onAuthError,
|
|
9719
9731
|
onFinish,
|
|
9720
9732
|
onMessage,
|
|
9733
|
+
onUsage,
|
|
9734
|
+
onData,
|
|
9721
9735
|
title,
|
|
9722
9736
|
initialAssistantMessage,
|
|
9723
9737
|
initialUserMessage,
|
|
@@ -9727,7 +9741,8 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
9727
9741
|
voice,
|
|
9728
9742
|
speechToText,
|
|
9729
9743
|
widgets,
|
|
9730
|
-
feedback
|
|
9744
|
+
feedback,
|
|
9745
|
+
showTokenUsage = false
|
|
9731
9746
|
}, ref) {
|
|
9732
9747
|
const [detectedDarkMode, setDetectedDarkMode] = useState9(() => detectChatWidgetDarkMode());
|
|
9733
9748
|
useEffect6(() => {
|
|
@@ -9809,7 +9824,8 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
9809
9824
|
addToolOutput,
|
|
9810
9825
|
addToolApprovalResponse,
|
|
9811
9826
|
pendingToolOutput,
|
|
9812
|
-
pendingToolApproval
|
|
9827
|
+
pendingToolApproval,
|
|
9828
|
+
usage
|
|
9813
9829
|
} = useChat({
|
|
9814
9830
|
api,
|
|
9815
9831
|
threadId,
|
|
@@ -9820,7 +9836,9 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
9820
9836
|
onError,
|
|
9821
9837
|
onAuthError,
|
|
9822
9838
|
onFinish,
|
|
9823
|
-
onMessage
|
|
9839
|
+
onMessage,
|
|
9840
|
+
onUsage,
|
|
9841
|
+
onData
|
|
9824
9842
|
});
|
|
9825
9843
|
const handleToolOutput = useCallback7((result) => {
|
|
9826
9844
|
if (pendingToolOutput && addToolOutput) {
|
|
@@ -10121,6 +10139,18 @@ var ChatWidget = forwardRef(function ChatWidget2({
|
|
|
10121
10139
|
]
|
|
10122
10140
|
}
|
|
10123
10141
|
),
|
|
10142
|
+
showTokenUsage && usage && /* @__PURE__ */ jsxs15("div", { className: classNames2.tokenUsage, "aria-label": "Token usage", children: [
|
|
10143
|
+
/* @__PURE__ */ jsxs15("span", { className: classNames2.tokenUsageItem, title: "Input tokens", children: [
|
|
10144
|
+
"\u2191 ",
|
|
10145
|
+
usage.inputTokens.toLocaleString(),
|
|
10146
|
+
" in"
|
|
10147
|
+
] }),
|
|
10148
|
+
/* @__PURE__ */ jsxs15("span", { className: classNames2.tokenUsageItem, title: "Output tokens", children: [
|
|
10149
|
+
"\u2193 ",
|
|
10150
|
+
usage.outputTokens.toLocaleString(),
|
|
10151
|
+
" out"
|
|
10152
|
+
] })
|
|
10153
|
+
] }),
|
|
10124
10154
|
/* @__PURE__ */ jsx18("div", { className: classNames2.inputContainer, children: /* @__PURE__ */ jsxs15("form", { onSubmit: handleSubmit, className: classNames2.inputForm, children: [
|
|
10125
10155
|
/* @__PURE__ */ jsx18(
|
|
10126
10156
|
"textarea",
|
|
@@ -10932,6 +10962,7 @@ export {
|
|
|
10932
10962
|
createSDKWidget,
|
|
10933
10963
|
createWidget,
|
|
10934
10964
|
defaultChatWidgets,
|
|
10965
|
+
extractUsageData,
|
|
10935
10966
|
fetchApprovalConfig,
|
|
10936
10967
|
getVendorCardsWidget,
|
|
10937
10968
|
isSDKWidget,
|