npm package: @sprout_ai_labs/sidekick
Description: A Vue 3 plugin providing responsive chat components with custom Sidekick branding and shared state management
Author: Louie Jocson
Latest version: 1.2.26

# Sprout Sidekick

A Vue 3 plugin providing responsive chat components with custom Sidekick branding, Rubik font, and shared state management.

[![Demo](https://img.shields.io/badge/🚀-Live%20Demo-blue?style=for-the-badge)](https://ljocson.github.io/sidekick/demo)

## Features

- 🎨 **Custom Branding**: Built-in Sidekick design with Rubik font
- 💬 **Unified Components**: Ready-to-use chat interface with built-in state management
- 🎯 **Standalone Components**: Flexible, store-independent components for custom state management
- 🔄 **Shared State**: Automatic state synchronization (unified components)
- 🧠 **Thinking Process**: Collapsible thought displays with streaming animations
- 📱 **Responsive**: Mobile-friendly design
- 💻 **TypeScript**: Full TypeScript support with comprehensive types
- 🎨 **Tailwind CSS**: Styled with Tailwind CSS
- ⚡ **Vue 3**: Built for Vue 3 with Composition API
- 🔔 **Error Handling**: Built-in snackbar notifications for errors and success messages
- 📝 **Markdown Support**: Rich text rendering in messages
- 🔍 **KB Sources**: Citation support for knowledge base sources
- 📊 **Analytics Control**: Optional analytics tracking with standalone mode support

## Demo

🚀 **[Try the Live Demo](https://ljocson.github.io/sidekick/demo)** - See the components in action with interactive examples.

## Installation

```bash
npm install @sprout_ai_labs/sidekick
```

## Quick Start

### 1. Install the plugin

```javascript
import { createApp } from 'vue'
import App from './App.vue'
import SproutSidekick from '@sprout_ai_labs/sidekick'
import '@sprout_ai_labs/sidekick/dist/sprout-sidekick.css'

const app = createApp(App)

app.use(SproutSidekick, {
  mode: 'PROD', // Required: 'QA' or 'PROD'
  appName: 'My Application', // Required: Your app name (used for analytics)
  skipDesignSystem: true, // Optional: Skip if design system is already installed
})

app.mount('#app')
```

### 2. Use the components

```vue
<template>
  <div>
    <!-- Full chat interface -->
    <SidekickChat />

    <!-- Floating chat widget -->
    <SidekickChatPlugin />
  </div>
</template>

<script setup>
import { useChatStore } from '@sprout_ai_labs/sidekick'

const chatStore = useChatStore()

onMounted(() => {
  // Set the token
  chatStore.setToken('your-token-here')
})
</script>
```

## Components

The plugin provides two types of components:

### 🔄 Unified Components (with built-in store)

Perfect for quick setup with automatic state management:

#### SidekickChat

The main chat interface component for full-page chat experiences.

```vue
<SidekickChat />
```

#### SidekickChatPlugin

A floating chat widget component that can be positioned anywhere on the page.

```vue
<SidekickChatPlugin />
```

### 🎯 Standalone Components (no store dependencies)

Perfect for custom state management and maximum flexibility:

```vue
<script setup>
import {
  SidekickMessages,
  SidekickChatInput,
  SidekickCollapsibleThought,
  SidekickCollapsibleThoughtStreaming
} from '@sprout_ai_labs/sidekick'
</script>

<template>
  <!-- Message display with streaming support -->
  <SidekickMessages
    :messages="messages"
    :is-typing="isTyping"
    :current-thoughts="currentThoughts"
    :current-chunked-message="currentChunkedMessage"
  />

  <!-- Chat input with auto-expand -->
  <SidekickChatInput
    @submit="handleSubmit"
    @input="handleInput"
  />

  <!-- Completed thinking process -->
  <SidekickCollapsibleThought
    :steps="thoughtSteps"
    :duration="thinkingDuration"
  />

  <!-- Real-time streaming thoughts -->
  <SidekickCollapsibleThoughtStreaming
    :steps="liveThoughts"
  />
</template>
```

**Standalone components** work via props and events only - no store required! Perfect for:
- Integrating into existing applications with custom state
- Building chat interfaces in Sidekick Central
- Maximum control over state management

See the [Standalone Components Documentation](https://spr-sidekick-docs.azurewebsites.net/api/standalone-components) for full details.

### 🛠️ Utility Components

- `SidekickLoader` - Animated loading indicator
- `SidekickLogo` - Sidekick logo component
- `SidekickChatSources` - Knowledge base source citations

## Plugin Options

```typescript
interface SidekickChatOptions {
  mode: 'QA' | 'PROD' | 'qa' | 'prod' // Required: Backend environment
  appName: string // Required: Your application name (for analytics)
  skipDesignSystem?: boolean // Optional: Skip design system installation
  baseUrl?: string // Optional: Custom backend URL (overrides mode)
  deviceSource?: 'mobile' | 'web' // Optional: Device type (default: 'web')
  standalone?: boolean // Optional: Disable analytics tracking (default: false)
}
```

### Required Parameters

- **`mode`**: Specifies which backend environment to use (`'QA'` or `'PROD'`)
- **`appName`**: Identifies your application in analytics tracking

### Optional Parameters

- **`baseUrl`**: Custom backend URL (takes precedence over `mode`)
- **`deviceSource`**: Device type identifier (`'mobile'` or `'web'`, default: `'web'`)
- **`skipDesignSystem`**: Skip design system installation if already installed
- **`standalone`**: Disable analytics tracking when `true` (default: `false`)

### Environment Variables

The plugin requires environment variables to be set in your `.env` file:

```env
VITE_CHAT_BE_QA=https://agent-center-be-qa.sprout.ph
VITE_CHAT_BE_PROD=https://agent-center-be.sprout.ph
```

### Configuration Examples

**Minimal configuration (QA environment):**

```javascript
app.use(SproutSidekickPlugin, {
  mode: 'QA', // Required
  appName: 'Sprout HR', // Required
})
```

**Production configuration:**

```javascript
app.use(SproutSidekickPlugin, {
  mode: 'PROD', // Required
  appName: 'Sprout Payroll', // Required
  skipDesignSystem: true,
})
```

**Mobile app configuration:**

```javascript
app.use(SproutSidekickPlugin, {
  mode: 'PROD', // Required
  appName: 'Sprout Mobile', // Required
  deviceSource: 'mobile', // Optional
})
```

**Using custom baseUrl:**

```javascript
app.use(SproutSidekickPlugin, {
  mode: 'QA', // Required (even though baseUrl will override)
  appName: 'Custom App', // Required
  baseUrl: 'https://my-custom-backend.com', // This URL will be used
})
```

**Standalone mode (disable analytics):**

```javascript
app.use(SproutSidekickPlugin, {
  mode: 'PROD', // Required
  appName: 'My App', // Required
  standalone: true, // Disables all analytics tracking
})
```

**Priority Order for Backend URL:**

1. `baseUrl` (if provided) - highest priority
2. `mode` (uses corresponding environment variable)
3. Throws error if neither is properly configured

::: warning
Both `mode` and `appName` are **required**. The plugin will throw an error at installation time if either is missing.
:::

### Analytics Tracking

By default, the plugin tracks analytics for all chat interactions. You can disable analytics by setting `standalone: true`:

```javascript
// Analytics enabled (default)
app.use(SproutSidekickPlugin, {
  mode: 'PROD',
  appName: 'My App',
  // standalone: false (default)
})

// Analytics disabled
app.use(SproutSidekickPlugin, {
  mode: 'PROD',
  appName: 'My App',
  standalone: true, // All analytics calls are skipped
})
```

When `standalone: true` is set:
- All analytics logging is disabled
- No data is sent to the analytics endpoints
- Feature flag validation calls are skipped
- Perfect for development, testing, or privacy-focused implementations

### Design System Handling

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.

**Automatic Detection**: The plugin checks for existing design system components before installation.

**Manual Control**: You can explicitly skip design system installation:

```javascript
app.use(SproutSidekickPlugin, {
  skipDesignSystem: true, // Skip design system installation
})
```

**Use Cases for `skipDesignSystem: true`**:

- Your application already has the design system installed
- You want to use a different version of the design system
- You're managing design system installation separately

## Error Handling

The plugin includes built-in error handling with user-friendly snackbar notifications for various scenarios:

- **Authentication Errors**: Invalid tokens, expired sessions, permission issues
- **Message Sending Failures**: Network connectivity, server errors, validation issues
- **Session Management**: Errors when clearing conversations or managing sessions
- **Network Issues**: Connection timeouts, offline status, server unavailability

Error notifications appear automatically using the design system's snackbar component and provide specific, actionable feedback to users.

## State Management

Use the built-in chat store for state management:

```javascript
import { useChatStore } from '@sprout_ai_labs/sidekick'

const chatStore = useChatStore()

// Access chat state
console.log(chatStore.messages)
console.log(chatStore.isTyping)

// Send a message
chatStore.sendMessage('Hello, world!')

// Authentication
chatStore.setToken('your-token')
chatStore.clearToken()
```

## Types

The plugin exports comprehensive TypeScript types:

```typescript
// Plugin options
interface SidekickChatOptions {
  mode: 'QA' | 'PROD' | 'qa' | 'prod'
  appName: string
  skipDesignSystem?: boolean
  baseUrl?: string
  deviceSource?: 'mobile' | 'web'
  standalone?: boolean
}

// Chat message
interface ChatMessage {
  id: string
  text: string
  sender: 'user' | 'bot' | 'ticket'
  timestamp: Date
  isStreaming?: boolean
  thoughtSteps?: ThoughtStep[]
  thinkingDuration?: number
  isError?: boolean
  errorDetails?: ErrorDetails
  feedback?: Feedback
  analyticsId?: string
  redactedText?: string
  kbSources?: KBSource[]
  coeDetails?: CoeDetails
}

// Chat state
interface ChatState {
  messages: ChatMessage[]
  isTyping: boolean
  isConnected: boolean
  token: string | null
  isOpen: boolean
  user: AuthUser | null
  currentStreamingMessage: ChatMessage | null
}
```

See the full [TypeScript definitions](./dist/index.d.ts) for all available types.

## Development

```bash
# Install dependencies
npm install

# Start development server
npm run dev

# Build the library
npm run build

# Run tests
npm run test:unit

# Lint code
npm run lint
```

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.