@sprout_ai_labs/sidekick 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,305 @@
1
+ # Sprout Sidekick
2
+
3
+ A Vue 3 plugin providing responsive chat components with custom Sidekick branding, Rubik font, and shared state management.
4
+
5
+ [![Demo](https://img.shields.io/badge/🚀-Live%20Demo-blue?style=for-the-badge)](https://ljocson.github.io/sidekick/demo)
6
+
7
+ ## Features
8
+
9
+ - 🎨 **Custom Branding**: Built-in Sidekick design with Rubik font
10
+ - 💬 **Chat Components**: Ready-to-use chat interface components
11
+ - 🔄 **Shared State**: Automatic state synchronization between components
12
+ - 📱 **Responsive**: Mobile-friendly design
13
+ - 🎯 **TypeScript**: Full TypeScript support
14
+ - 🎨 **Tailwind CSS**: Styled with Tailwind CSS
15
+ - âš¡ **Vue 3**: Built for Vue 3 with Composition API
16
+ - 🔔 **Error Handling**: Built-in snackbar notifications for errors and success messages
17
+
18
+ ## Demo
19
+
20
+ 🚀 **[Try the Live Demo](https://ljocson.github.io/sidekick/demo)** - See the components in action with interactive examples.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @sprout_ai_labs/sidekick
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ ### 1. Install the plugin
31
+
32
+ ```javascript
33
+ import { createApp } from 'vue'
34
+ import App from './App.vue'
35
+ import SproutSidekick from '@sprout_ai_labs/sidekick'
36
+ import '@sprout_ai_labs/sidekick/dist/sprout-sidekick.css'
37
+
38
+ const app = createApp(App)
39
+
40
+ app.use(SproutSidekick, {
41
+ mode: 'PROD', // Required: 'QA' or 'PROD'
42
+ appName: 'My Application', // Required: Your app name (used for analytics)
43
+ skipDesignSystem: true, // Optional: Skip if design system is already installed
44
+ })
45
+
46
+ app.mount('#app')
47
+ ```
48
+
49
+ ### 2. Use the components
50
+
51
+ ```vue
52
+ <template>
53
+ <div>
54
+ <!-- Full chat interface -->
55
+ <SidekickChat />
56
+
57
+ <!-- Floating chat widget -->
58
+ <SidekickChatPlugin />
59
+ </div>
60
+ </template>
61
+
62
+ <script setup>
63
+ import { useChatStore } from '@sprout_ai_labs/sidekick'
64
+
65
+ const chatStore = useChatStore()
66
+
67
+ onMounted(() => {
68
+ // Set the token
69
+ chatStore.setToken('your-token-here')
70
+ })
71
+ </script>
72
+ ```
73
+
74
+ ## Components
75
+
76
+ ### SidekickChat
77
+
78
+ The main chat interface component for full-page chat experiences.
79
+
80
+ ```vue
81
+ <SidekickChat />
82
+ ```
83
+
84
+ ### SidekickChatPlugin
85
+
86
+ A floating chat widget component that can be positioned anywhere on the page.
87
+
88
+ ```vue
89
+ <SidekickChatPlugin />
90
+ ```
91
+
92
+ ### Additional Components
93
+
94
+ The plugin also includes:
95
+
96
+ - `SidekickChatInput` - Standalone chat input component
97
+ - `SidekickLoader` - Loading animation component
98
+ - `SidekickMessages` - Message display component
99
+
100
+ ## Plugin Options
101
+
102
+ ```typescript
103
+ interface SidekickChatOptions {
104
+ mode: 'QA' | 'PROD' | 'qa' | 'prod' // Required: Backend environment
105
+ appName: string // Required: Your application name (for analytics)
106
+ skipDesignSystem?: boolean // Optional: Skip design system installation
107
+ baseUrl?: string // Optional: Custom backend URL (overrides mode)
108
+ deviceSource?: 'mobile' | 'web' // Optional: Device type (default: 'web')
109
+ }
110
+ ```
111
+
112
+ ### Required Parameters
113
+
114
+ - **`mode`**: Specifies which backend environment to use (`'QA'` or `'PROD'`)
115
+ - **`appName`**: Identifies your application in analytics tracking
116
+
117
+ ### Optional Parameters
118
+
119
+ - **`baseUrl`**: Custom backend URL (takes precedence over `mode`)
120
+ - **`deviceSource`**: Device type identifier (`'mobile'` or `'web'`, default: `'web'`)
121
+ - **`skipDesignSystem`**: Skip design system installation if already installed
122
+
123
+ ### Environment Variables
124
+
125
+ The plugin requires environment variables to be set in your `.env` file:
126
+
127
+ ```env
128
+ VITE_CHAT_BE_QA=https://agent-center-be-qa.sprout.ph
129
+ VITE_CHAT_BE_PROD=https://agent-center-be.sprout.ph
130
+ ```
131
+
132
+ ### Configuration Examples
133
+
134
+ **Minimal configuration (QA environment):**
135
+
136
+ ```javascript
137
+ app.use(SproutSidekickPlugin, {
138
+ mode: 'QA', // Required
139
+ appName: 'Sprout HR', // Required
140
+ })
141
+ ```
142
+
143
+ **Production configuration:**
144
+
145
+ ```javascript
146
+ app.use(SproutSidekickPlugin, {
147
+ mode: 'PROD', // Required
148
+ appName: 'Sprout Payroll', // Required
149
+ skipDesignSystem: true,
150
+ })
151
+ ```
152
+
153
+ **Mobile app configuration:**
154
+
155
+ ```javascript
156
+ app.use(SproutSidekickPlugin, {
157
+ mode: 'PROD', // Required
158
+ appName: 'Sprout Mobile', // Required
159
+ deviceSource: 'mobile', // Optional
160
+ })
161
+ ```
162
+
163
+ **Using custom baseUrl:**
164
+
165
+ ```javascript
166
+ app.use(SproutSidekickPlugin, {
167
+ mode: 'QA', // Required (even though baseUrl will override)
168
+ appName: 'Custom App', // Required
169
+ baseUrl: 'https://my-custom-backend.com', // This URL will be used
170
+ })
171
+ ```
172
+
173
+ **Priority Order for Backend URL:**
174
+
175
+ 1. `baseUrl` (if provided) - highest priority
176
+ 2. `mode` (uses corresponding environment variable)
177
+ 3. Throws error if neither is properly configured
178
+
179
+ ::: warning
180
+ Both `mode` and `appName` are **required**. The plugin will throw an error at installation time if either is missing.
181
+ :::
182
+
183
+ ### Design System Handling
184
+
185
+ The plugin automatically detects if the Sprout Design System is already installed in your application to prevent duplicate installations. This ensures optimal performance and avoids conflicts.
186
+
187
+ **Automatic Detection**: The plugin checks for existing design system components before installation.
188
+
189
+ **Manual Control**: You can explicitly skip design system installation:
190
+
191
+ ```javascript
192
+ app.use(SproutSidekickPlugin, {
193
+ skipDesignSystem: true, // Skip design system installation
194
+ })
195
+ ```
196
+
197
+ **Use Cases for `skipDesignSystem: true`**:
198
+
199
+ - Your application already has the design system installed
200
+ - You want to use a different version of the design system
201
+ - You're managing design system installation separately
202
+
203
+ ## Error Handling
204
+
205
+ The plugin includes built-in error handling with user-friendly snackbar notifications for various scenarios:
206
+
207
+ - **Authentication Errors**: Invalid tokens, expired sessions, permission issues
208
+ - **Message Sending Failures**: Network connectivity, server errors, validation issues
209
+ - **Session Management**: Errors when clearing conversations or managing sessions
210
+ - **Network Issues**: Connection timeouts, offline status, server unavailability
211
+
212
+ Error notifications appear automatically using the design system's snackbar component and provide specific, actionable feedback to users.
213
+
214
+ ## State Management
215
+
216
+ Use the built-in chat store for state management:
217
+
218
+ ```javascript
219
+ import { useChatStore } from '@sprout_ai_labs/sidekick'
220
+
221
+ const chatStore = useChatStore()
222
+
223
+ // Access chat state
224
+ console.log(chatStore.messages)
225
+ console.log(chatStore.isTyping)
226
+
227
+ // Send a message
228
+ chatStore.sendMessage('Hello, world!')
229
+
230
+ // Authentication
231
+ chatStore.setToken('your-token')
232
+ chatStore.clearToken()
233
+ ```
234
+
235
+ ## Types
236
+
237
+ The plugin exports comprehensive TypeScript types:
238
+
239
+ ```typescript
240
+ // Plugin options
241
+ interface SidekickChatOptions {
242
+ mode: 'QA' | 'PROD' | 'qa' | 'prod'
243
+ appName: string
244
+ skipDesignSystem?: boolean
245
+ baseUrl?: string
246
+ deviceSource?: 'mobile' | 'web'
247
+ }
248
+
249
+ // Chat message
250
+ interface ChatMessage {
251
+ id: string
252
+ text: string
253
+ sender: 'user' | 'bot' | 'ticket'
254
+ timestamp: Date
255
+ isStreaming?: boolean
256
+ thoughtSteps?: ThoughtStep[]
257
+ thinkingDuration?: number
258
+ isError?: boolean
259
+ errorDetails?: ErrorDetails
260
+ feedback?: Feedback
261
+ analyticsId?: string
262
+ redactedText?: string
263
+ kbSources?: KBSource[]
264
+ }
265
+
266
+ // Chat state
267
+ interface ChatState {
268
+ messages: ChatMessage[]
269
+ isTyping: boolean
270
+ isConnected: boolean
271
+ token: string | null
272
+ isOpen: boolean
273
+ user: AuthUser | null
274
+ currentStreamingMessage: ChatMessage | null
275
+ }
276
+ ```
277
+
278
+ See the full [TypeScript definitions](./dist/index.d.ts) for all available types.
279
+
280
+ ## Development
281
+
282
+ ```bash
283
+ # Install dependencies
284
+ npm install
285
+
286
+ # Start development server
287
+ npm run dev
288
+
289
+ # Build the library
290
+ npm run build
291
+
292
+ # Run tests
293
+ npm run test:unit
294
+
295
+ # Lint code
296
+ npm run lint
297
+ ```
298
+
299
+ ## License
300
+
301
+ MIT
302
+
303
+ ## Contributing
304
+
305
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,122 @@
1
+ import type { App, Plugin } from 'vue'
2
+
3
+ // Plugin options interface
4
+ export interface SidekickChatOptions {
5
+ mode: 'QA' | 'PROD' | 'qa' | 'prod'
6
+ appName: string
7
+ skipDesignSystem?: boolean
8
+ baseUrl?: string
9
+ deviceSource?: 'mobile' | 'web'
10
+ }
11
+
12
+ // KB Source interface
13
+ export interface KBSource {
14
+ id: string
15
+ title: string
16
+ url: string
17
+ snippet: string[]
18
+ }
19
+
20
+ // Feedback interface
21
+ export interface Feedback {
22
+ is_helpful?: boolean
23
+ is_not_helpful?: boolean
24
+ user_feedback?: string
25
+ user_feedback_more?: string
26
+ analytics_id?: string
27
+ }
28
+
29
+ // Error details interface
30
+ export interface ErrorDetails {
31
+ code: string
32
+ status: number
33
+ message: string
34
+ file?: string
35
+ line?: string
36
+ lineno?: number
37
+ traceback?: string
38
+ }
39
+
40
+ // Thought step interface
41
+ export interface ThoughtStep {
42
+ event: string
43
+ message: string
44
+ agent_name?: string
45
+ agent_id?: string
46
+ tool_details?: Record<string, unknown>
47
+ completed: boolean
48
+ }
49
+
50
+ // Chat message interface
51
+ export interface ChatMessage {
52
+ id: string
53
+ text: string
54
+ sender: 'user' | 'bot' | 'ticket'
55
+ timestamp: Date
56
+ isStreaming?: boolean
57
+ thoughtSteps?: ThoughtStep[]
58
+ thinkingDuration?: number
59
+ isError?: boolean
60
+ errorDetails?: ErrorDetails
61
+ feedback?: Feedback
62
+ analyticsId?: string
63
+ redactedText?: string
64
+ kbSources?: KBSource[]
65
+ }
66
+
67
+ // Auth user interface
68
+ export interface AuthUser {
69
+ agentCenterUserId: string
70
+ accessLevel: string
71
+ agentCenterAccessLevel: string
72
+ hrDomain: string
73
+ employeeId: string
74
+ sessionId: string
75
+ realm: string
76
+ companyId: string
77
+ userId: string
78
+ email: string
79
+ company?: string
80
+ clientId?: string
81
+ viewingType?: string
82
+ }
83
+
84
+ // Chat state interface
85
+ export interface ChatState {
86
+ messages: ChatMessage[]
87
+ isTyping: boolean
88
+ isConnected: boolean
89
+ token: string | null
90
+ isOpen: boolean
91
+ user: AuthUser | null
92
+ currentStreamingMessage: ChatMessage | null
93
+ }
94
+
95
+ // Snackbar message interface
96
+ export interface SnackbarMessage {
97
+ id: string
98
+ message: string
99
+ type: 'success' | 'error' | 'warning' | 'info'
100
+ duration?: number
101
+ }
102
+
103
+ // Vue components
104
+ export declare const SidekickChat: any
105
+ export declare const SidekickChatPlugin: any
106
+ export declare const SidekickLoader: any
107
+ export declare const SidekickChatInput: any
108
+
109
+ // Store composable
110
+ export declare function useChatStore(options?: SidekickChatOptions): any
111
+
112
+ // Snackbar composable
113
+ export declare function useSnackbar(): any
114
+
115
+ // Storage utilities
116
+ export declare const storageUtils: any
117
+
118
+ // Plugin exports
119
+ declare const SproutSidekickPlugin: Plugin<[SidekickChatOptions]>
120
+ export default SproutSidekickPlugin
121
+
122
+ export declare const VueSidekickChat: Plugin<[SidekickChatOptions]>