@blockspark/chat-widget 1.0.0 → 1.0.2

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
@@ -1,57 +1,88 @@
1
1
  # BlockSpark Chat Widget
2
2
 
3
- A reusable React chat widget component that connects directly with Dialogflow CX - no backend API required!
3
+ A reusable chat widget for **React**, **Next.js**, **Vue 3**, and **vanilla HTML (CDN)** that connects directly with Dialogflow CX no backend API required.
4
4
 
5
5
  ## Installation
6
6
 
7
- ### Option 1: Install from Local Path (Recommended for Development)
7
+ Install from npm (for React, Next.js, or Vue projects):
8
8
 
9
9
  ```bash
10
- # In your website project directory
11
- npm install /path/to/blockspark-chat-widget
12
- # or
13
- npm install ../blockspark-chat-widget
10
+ npm install @blockspark/chat-widget
14
11
  ```
15
12
 
16
- ### Option 2: Use npm link (For Development)
13
+ - **React / Next.js**: You also need `react` and `react-dom` (they are peer dependencies).
14
+ - **Vue 3**: You also need `vue`. The widget bundles React internally for the Vue build, so you do **not** need to install React.
17
15
 
18
16
  ```bash
19
- # In the blockspark-chat-widget directory
20
- npm link
17
+ # React or Next.js
18
+ npm install @blockspark/chat-widget react react-dom
21
19
 
22
- # In your website project directory
23
- npm link @blockspark/chat-widget
20
+ # Vue 3 only
21
+ npm install @blockspark/chat-widget vue
24
22
  ```
25
23
 
26
- ### Option 3: Publish to npm (For Production)
24
+ **Development / local testing:**
27
25
 
28
26
  ```bash
29
- # Build the library first
30
- npm run build
31
-
32
- # Publish to npm (make sure you're logged in)
33
- npm publish
27
+ # From your app directory
28
+ npm install /path/to/blockspark-chat-widget
29
+ # or use npm link in the widget repo, then npm link @blockspark/chat-widget in your app
34
30
  ```
35
31
 
36
- Then install in your project:
37
- ```bash
38
- npm install @blockspark/chat-widget
39
- ```
32
+ ---
40
33
 
41
34
  ## Usage
42
35
 
43
- ### Basic Usage
36
+ ### React
37
+
38
+ Import the component and the default styles, then render with your config.
44
39
 
45
40
  ```tsx
46
41
  import ChatWidget from '@blockspark/chat-widget';
47
42
  import '@blockspark/chat-widget/dist/styles.css';
48
43
 
49
- // Load your Google Cloud service account key
50
44
  import serviceAccountKey from './path/to/service-account-key.json';
51
45
 
52
46
  function App() {
47
+ return (
48
+ <ChatWidget
49
+ dfProjectId="your-project-id"
50
+ dfLocation="us-central1"
51
+ dfAgentId="your-agent-id"
52
+ serviceAccountKey={serviceAccountKey}
53
+ languageCode="en"
54
+ title="💬 My Chat"
55
+ subtitle="We're here to help"
56
+ />
57
+ );
58
+ }
59
+ ```
60
+
61
+ ### Next.js
62
+
63
+ The widget uses browser APIs (e.g. `localStorage`) and is intended to run on the client. Use **dynamic import with SSR disabled** so it only loads in the browser.
64
+
65
+ **App Router (Next.js 13+):**
66
+
67
+ ```tsx
68
+ 'use client';
69
+
70
+ import dynamic from 'next/dynamic';
71
+ import '@blockspark/chat-widget/dist/styles.css';
72
+
73
+ const ChatWidget = dynamic(
74
+ () => import('@blockspark/chat-widget').then((mod) => mod.default),
75
+ { ssr: false }
76
+ );
77
+
78
+ export default function Page() {
79
+ const serviceAccountKey = {
80
+ /* your key object, or load from env/server */
81
+ };
82
+
53
83
  return (
54
84
  <div>
85
+ <h1>My Page</h1>
55
86
  <ChatWidget
56
87
  dfProjectId="your-project-id"
57
88
  dfLocation="us-central1"
@@ -64,71 +95,166 @@ function App() {
64
95
  }
65
96
  ```
66
97
 
67
- ### Using Access Token (Alternative)
68
-
69
- If you prefer to manage authentication yourself:
98
+ **Pages Router:**
70
99
 
71
100
  ```tsx
72
- import ChatWidget from '@blockspark/chat-widget';
101
+ import dynamic from 'next/dynamic';
73
102
  import '@blockspark/chat-widget/dist/styles.css';
74
103
 
75
- function App() {
76
- const [accessToken, setAccessToken] = useState<string>('');
77
-
78
- // Get access token from your backend or OAuth flow
79
- useEffect(() => {
80
- // Your token fetching logic here
81
- fetchAccessToken().then(setAccessToken);
82
- }, []);
104
+ const ChatWidget = dynamic(
105
+ () => import('@blockspark/chat-widget').then((mod) => mod.default),
106
+ { ssr: false }
107
+ );
83
108
 
109
+ export default function ChatPage() {
84
110
  return (
85
111
  <ChatWidget
86
112
  dfProjectId="your-project-id"
87
113
  dfLocation="us-central1"
88
114
  dfAgentId="your-agent-id"
89
- accessToken={accessToken}
115
+ serviceAccountKey={process.env.NEXT_PUBLIC_SERVICE_ACCOUNT_KEY_JSON ? JSON.parse(process.env.NEXT_PUBLIC_SERVICE_ACCOUNT_KEY_JSON) : undefined}
90
116
  languageCode="en"
91
117
  />
92
118
  );
93
119
  }
94
120
  ```
95
121
 
96
- ### With Custom Configuration
122
+ **Important:** Do not expose raw service account keys in client-side code in production. Prefer a backend that returns short-lived tokens or use a proxy.
97
123
 
98
- ```tsx
99
- import ChatWidget from '@blockspark/chat-widget';
124
+ ### Vue 3
125
+
126
+ Use either the global plugin or the component directly.
127
+
128
+ **Option A — Global plugin (e.g. `main.js` / `main.ts`):**
129
+
130
+ ```js
131
+ import { createApp } from 'vue';
132
+ import App from './App.vue';
133
+ import BlockSparkChatWidget from '@blockspark/chat-widget/vue';
100
134
  import '@blockspark/chat-widget/dist/styles.css';
101
- import serviceAccountKey from './service-account-key.json';
102
135
 
103
- function App() {
104
- return (
105
- <ChatWidget
106
- dfProjectId="your-project-id"
107
- dfLocation="us-central1"
108
- dfAgentId="your-agent-id"
109
- serviceAccountKey={serviceAccountKey}
110
- languageCode="en"
111
- title="💬 My Chat Assistant"
112
- subtitle="How can I help you?"
113
- welcomeTitle="👋 Welcome!"
114
- welcomeMessage="I'm here to help you with any questions."
115
- welcomeCta="Start chatting"
116
- showWelcomePopup={true}
117
- welcomePopupDelay={2000}
118
- inputPlaceholder="Type your message..."
119
- emptyStateMessage="Hi! How can I help you today?"
120
- debug={false}
121
- />
122
- );
123
- }
136
+ const app = createApp(App);
137
+ app.use(BlockSparkChatWidget); // registers <BlockSparkChatWidget>
138
+ app.mount('#app');
124
139
  ```
125
140
 
126
- ### Import Types (TypeScript)
141
+ Then in any template:
142
+
143
+ ```vue
144
+ <template>
145
+ <BlockSparkChatWidget
146
+ df-project-id="your-project-id"
147
+ df-location="us-central1"
148
+ df-agent-id="your-agent-id"
149
+ :service-account-key="serviceAccountKey"
150
+ language-code="en"
151
+ />
152
+ </template>
153
+ ```
127
154
 
128
- ```tsx
129
- import ChatWidget, { ChatWidgetProps, DialogflowConfig } from '@blockspark/chat-widget';
155
+ **Option B — Component only:**
156
+
157
+ ```vue
158
+ <script setup>
159
+ import { BlockSparkChatWidgetVue } from '@blockspark/chat-widget/vue';
160
+ import '@blockspark/chat-widget/dist/styles.css';
161
+
162
+ import serviceAccountKey from './path/to/service-account-key.json';
163
+ </script>
164
+
165
+ <template>
166
+ <BlockSparkChatWidgetVue
167
+ df-project-id="your-project-id"
168
+ df-location="us-central1"
169
+ df-agent-id="your-agent-id"
170
+ :service-account-key="serviceAccountKey"
171
+ language-code="en"
172
+ />
173
+ </template>
174
+ ```
175
+
176
+ Use **kebab-case** for props in templates (e.g. `df-project-id`, `service-account-key`). All props from the Props table below are supported.
177
+
178
+ ### CDN (script tag, no build step)
179
+
180
+ You can load the widget from a CDN and mount it with React (the widget is a React component). Load React, ReactDOM, the widget CSS, and the widget script, then render into a container.
181
+
182
+ Replace `1.0.1` with the version you want (or use `latest` for the latest release).
183
+
184
+ **Using unpkg:**
185
+
186
+ ```html
187
+ <!DOCTYPE html>
188
+ <html lang="en">
189
+ <head>
190
+ <meta charset="UTF-8" />
191
+ <title>BlockSpark Chat Widget</title>
192
+ <!-- 1. React (required by the widget) -->
193
+ <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
194
+ <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
195
+ <!-- 2. Widget CSS -->
196
+ <link rel="stylesheet" href="https://unpkg.com/@blockspark/chat-widget@1.0.1/dist/styles.css" />
197
+ </head>
198
+ <body>
199
+ <div id="chat-root"></div>
200
+
201
+ <!-- 3. Widget script (UMD: exposes BlockSparkChatWidget) -->
202
+ <script src="https://unpkg.com/@blockspark/chat-widget@1.0.1/dist/index.js"></script>
203
+
204
+ <script>
205
+ (function () {
206
+ var container = document.getElementById('chat-root');
207
+ var React = window.React;
208
+ var ReactDOM = window.ReactDOM;
209
+ var ChatWidget = window.BlockSparkChatWidget;
210
+
211
+ var config = {
212
+ dfProjectId: 'your-project-id',
213
+ dfLocation: 'us-central1',
214
+ dfAgentId: 'your-agent-id',
215
+ serviceAccountKey: { /* your service account key object */ },
216
+ languageCode: 'en',
217
+ title: '💬 BlockSpark AI Assistant',
218
+ subtitle: "We're here to help"
219
+ };
220
+
221
+ if (ReactDOM.createRoot) {
222
+ ReactDOM.createRoot(container).render(React.createElement(ChatWidget, config));
223
+ } else {
224
+ ReactDOM.render(React.createElement(ChatWidget, config), container);
225
+ }
226
+ })();
227
+ </script>
228
+ </body>
229
+ </html>
130
230
  ```
131
231
 
232
+ **Using jsDelivr:**
233
+
234
+ Use the same structure and swap the CDN base URL:
235
+
236
+ - CSS: `https://cdn.jsdelivr.net/npm/@blockspark/chat-widget@1.0.1/dist/styles.css`
237
+ - JS: `https://cdn.jsdelivr.net/npm/@blockspark/chat-widget@1.0.1/dist/index.js`
238
+
239
+ **Notes for CDN:**
240
+
241
+ - You must provide `serviceAccountKey` (or `accessToken`) in the config object. Do not hardcode real keys in production; use a backend or token endpoint.
242
+ - Pin the version in the URL (e.g. `@1.0.1`) instead of `@latest` for stable behavior.
243
+
244
+ ---
245
+
246
+ ## Human Support Mode
247
+
248
+ The widget supports automatic handoff from bot to human agents. When Dialogflow returns `{"handoff": true}`, the widget will:
249
+
250
+ 1. Switch from Bot Mode to Human Support Mode
251
+ 2. Create a support chat session
252
+ 3. Connect via WebSocket for real-time messaging
253
+ 4. Load message history
254
+ 5. Route messages to the backend API instead of Dialogflow
255
+
256
+ The widget shows mode and connection status in the chat header.
257
+
132
258
  ## Props
133
259
 
134
260
  | Prop | Type | Required | Default | Description |
@@ -150,60 +276,57 @@ import ChatWidget, { ChatWidgetProps, DialogflowConfig } from '@blockspark/chat-
150
276
  | `inputPlaceholder` | `string` | No | `"Type your message..."` | Input field placeholder |
151
277
  | `emptyStateMessage` | `string` | No | `"Hi! I'm BlockSpark..."` | Empty state message |
152
278
  | `debug` | `boolean` | No | `false` | Enable debug logging |
279
+ | `backendBaseUrl` | `string` | No | env or `"http://localhost:8012"` | Backend REST API base URL for Human Support Mode |
280
+ | `backendWsUrl` | `string` | No | env or `"ws://localhost:8012"` | Backend WebSocket URL for Human Support Mode |
153
281
 
154
282
  \* Either `serviceAccountKey` or `accessToken` must be provided.
155
283
 
284
+ ## TypeScript
285
+
286
+ ```tsx
287
+ import ChatWidget, { ChatWidgetProps, DialogflowConfig } from '@blockspark/chat-widget';
288
+ ```
289
+
156
290
  ## How It Works
157
291
 
158
- The widget connects **directly** to Dialogflow CX using the REST API - no backend required!
292
+ The widget talks **directly** to Dialogflow CX via the REST API (no custom backend required for basic use):
159
293
 
160
- 1. **Authentication**: Uses Google Cloud service account key to generate OAuth2 access tokens
161
- 2. **Session Management**: Creates and manages Dialogflow sessions automatically
162
- 3. **Message Handling**: Sends messages directly to Dialogflow and displays responses
163
- 4. **Rich Content**: Supports Dialogflow rich content (chips, cards, etc.)
294
+ 1. **Authentication** Uses a Google Cloud service account key to obtain OAuth2 access tokens
295
+ 2. **Sessions** Creates and manages Dialogflow sessions
296
+ 3. **Messages** Sends user messages to Dialogflow and displays responses
297
+ 4. **Rich content** Supports Dialogflow rich content (chips, cards, etc.)
164
298
 
165
299
  ## Requirements
166
300
 
167
- - React 16.8.0 or higher
168
- - React DOM 16.8.0 or higher
169
- - Google Cloud service account with Dialogflow API enabled
170
- - Dialogflow CX agent
301
+ - **React / Next.js**: React 16.8+ and React DOM
302
+ - **Vue**: Vue 3.x
303
+ - **CDN**: React 17 or 18 and React DOM loaded via script tags
304
+ - Google Cloud project with Dialogflow API enabled and a Dialogflow CX agent
171
305
 
172
306
  ## Getting Your Service Account Key
173
307
 
174
- 1. Go to [Google Cloud Console](https://console.cloud.google.com/)
175
- 2. Select your project
176
- 3. Navigate to **IAM & Admin** > **Service Accounts**
177
- 4. Create a new service account or select an existing one
178
- 5. Create a JSON key and download it
179
- 6. Enable **Dialogflow API** for your project
180
- 7. Grant the service account **Dialogflow API User** role
181
-
182
- ## Security Warning ⚠️
308
+ 1. Open [Google Cloud Console](https://console.cloud.google.com/) and select your project
309
+ 2. Go to **IAM & Admin** → **Service Accounts**
310
+ 3. Create or select a service account and create a JSON key
311
+ 4. Enable **Dialogflow API** for the project
312
+ 5. Grant the service account the **Dialogflow API User** role
183
313
 
184
- **Important**: Service account keys contain sensitive credentials.
314
+ ## Security
185
315
 
186
- - **For Development**: You can import the key directly (as shown in examples)
187
- - **For Production**:
188
- - **DO NOT** expose service account keys in client-side code
189
- - Use a backend proxy to handle authentication
190
- - Or use OAuth2 flow to get access tokens securely
191
- - Consider using restricted service account keys with minimal permissions
316
+ - **Development**: You can import or pass the service account key in code for local testing
317
+ - **Production**:
318
+ - **Do not** ship service account keys in client-side code or public HTML
319
+ - Prefer a backend that issues short-lived tokens or proxies Dialogflow calls
320
+ - Use restricted keys and minimal permissions where possible
192
321
 
193
322
  ## Development
194
323
 
195
324
  ```bash
196
- # Install dependencies
197
325
  npm install
198
-
199
- # Build for production
200
- npm run build
201
-
202
- # Watch mode for development
203
- npm run dev
326
+ npm run build # production build
327
+ npm run dev # watch mode
204
328
  ```
205
329
 
206
330
  ## License
207
331
 
208
332
  MIT
209
- export NPM_TOKEN=your_token_here
@@ -34,6 +34,10 @@ export interface ChatWidgetProps {
34
34
  accessToken?: string;
35
35
  /** Language code for Dialogflow */
36
36
  languageCode?: string;
37
+ /** Backend API base URL (default: http://localhost:8012) */
38
+ backendBaseUrl?: string;
39
+ /** WebSocket URL (default: ws://localhost:8012) */
40
+ backendWsUrl?: string;
37
41
  }
38
- export default function ChatWidget({ title, subtitle, welcomeTitle, welcomeMessage, welcomeCta, showWelcomePopup: enableWelcomePopup, welcomePopupDelay, fallbackWelcomeMessage, inputPlaceholder, emptyStateMessage, debug, dfProjectId, dfLocation, dfAgentId, serviceAccountKey, accessToken, languageCode, }: ChatWidgetProps): import("react/jsx-runtime").JSX.Element;
42
+ export default function ChatWidget({ title, subtitle, welcomeTitle, welcomeMessage, welcomeCta, showWelcomePopup: enableWelcomePopup, welcomePopupDelay, fallbackWelcomeMessage, inputPlaceholder, emptyStateMessage, debug, dfProjectId, dfLocation, dfAgentId, serviceAccountKey, accessToken, languageCode, backendBaseUrl, backendWsUrl, }: ChatWidgetProps): import("react/jsx-runtime").JSX.Element;
39
43
  //# sourceMappingURL=ChatWidget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../../src/components/ChatWidget.tsx"],"names":[],"mappings":"AAQA,OAAO,0BAA0B,CAAC;AAsBlC,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4CAA4C;IAC5C,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uCAAuC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mCAAmC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,GAAG,CAAC;IACxB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,KAAoC,EACpC,QAA+B,EAC/B,YAAyC,EACzC,cAAyE,EACzE,UAA+C,EAC/C,gBAAgB,EAAE,kBAAyB,EAC3C,iBAAwB,EACxB,sBAAwF,EACxF,gBAAyC,EACzC,iBAAgF,EAChF,KAAa,EACb,WAAW,EACX,UAA0B,EAC1B,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,YAAmB,GACpB,EAAE,eAAe,2CA6bjB"}
1
+ {"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../../src/components/ChatWidget.tsx"],"names":[],"mappings":"AAWA,OAAO,0BAA0B,CAAC;AAsBlC,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4CAA4C;IAC5C,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uCAAuC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mCAAmC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,GAAG,CAAC;IACxB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,KAAoC,EACpC,QAA+B,EAC/B,YAAyC,EACzC,cAAyE,EACzE,UAA+C,EAC/C,gBAAgB,EAAE,kBAAyB,EAC3C,iBAAwB,EACxB,sBAAwF,EACxF,gBAAyC,EACzC,iBAAgF,EAChF,KAAa,EACb,WAAW,EACX,UAA0B,EAC1B,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,YAAmB,EACnB,cAAc,EACd,YAAY,GACb,EAAE,eAAe,2CA03CjB"}
@@ -0,0 +1,17 @@
1
+ import type { ChatResponse } from "../services/dialogflowClient";
2
+ export type ChatMode = "BOT" | "HUMAN";
3
+ export interface UseChatModeReturn {
4
+ currentMode: ChatMode;
5
+ switchToHumanMode: () => void;
6
+ switchToBotMode: () => void;
7
+ isHandoffTriggered: (dialogflowResponse: ChatResponse) => boolean;
8
+ chatId: string | null;
9
+ sessionId: string | null;
10
+ setChatId: (id: string | null) => void;
11
+ setSessionId: (id: string | null) => void;
12
+ }
13
+ /**
14
+ * Hook to manage chat mode (BOT or HUMAN)
15
+ */
16
+ export declare function useChatMode(): UseChatModeReturn;
17
+ //# sourceMappingURL=useChatMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChatMode.d.ts","sourceRoot":"","sources":["../../src/hooks/useChatMode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;AAMvC,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,QAAQ,CAAC;IACtB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,kBAAkB,EAAE,CAAC,kBAAkB,EAAE,YAAY,KAAK,OAAO,CAAC;IAClE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC3C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,iBAAiB,CAmF/C"}