Quick Reference
Installation
bash
npm install @sprout_ai_labs/sidekickImport Statements
Unified Components (with store)
typescript
import { createApp } from 'vue'
import SproutSidekick from '@sprout_ai_labs/sidekick'
import '@sprout_ai_labs/sidekick/dist/sprout-sidekick.css'
// Install plugin
app.use(SproutSidekick, {
mode: 'PROD',
appName: 'My App',
})
// Use store
import { useChatStore } from '@sprout_ai_labs/sidekick'
const chatStore = useChatStore()Standalone Components (no store)
typescript
import {
SidekickMessages,
SidekickChatInput,
SidekickCollapsibleThought,
SidekickCollapsibleThoughtStreaming,
SidekickLoader,
SidekickLogo,
SidekickChatSources,
} from '@sprout_ai_labs/sidekick'
// CSS
import '@sprout_ai_labs/sidekick/dist/sprout-sidekick.css'Types
typescript
import type {
ChatMessage,
ChatState,
KBSource,
SidekickChatOptions,
} from '@sprout_ai_labs/sidekick'Component Quick Reference
SidekickMessages
vue
<SidekickMessages
:messages="messages"
:is-typing="false"
:current-thoughts="[]"
:current-chunked-message="''"
:streaming-animating="false"
/>Props:
messages:ChatMessage[]- Array of messagesisTyping:boolean- Show typing indicatorcurrentThoughts:ThoughtStep[]- Live thoughtscurrentChunkedMessage:string- Streaming messagestreamingAnimating:boolean- Enable shimmer
SidekickChatInput
vue
<SidekickChatInput
placeholder="Ask me anything..."
:placeholders="['Question 1', 'Question 2']"
:disabled="false"
:show-clear-button="true"
:auto-focus="false"
@submit="handleSubmit"
@input="handleInput"
@clear="handleClear"
/>Props:
placeholder:string- Default placeholderplaceholders:string[]- Cycling placeholdersdisabled:boolean- Disable inputshowClearButton:boolean- Show clear buttonmaxHeight:string- Max height (default: '120px')minHeight:string- Min height (default: '42px')autoFocus:boolean- Auto-focus on mount
Events:
@submit:(message: string) => void@input:(value: string) => void@clear:() => void
SidekickCollapsibleThought
vue
<SidekickCollapsibleThought :steps="thoughtSteps" :duration="5" />Props:
steps:ThinkingStep[]- Array of thought stepsduration:number- Duration in seconds (optional)
Step Interface:
typescript
interface ThinkingStep {
text: string // Step message
completed: boolean // Should be true for completed
event?: string // 'tool_call', 'observation', 'process', etc.
agent_name?: string
tool_details?: Record<string, unknown>
}SidekickCollapsibleThoughtStreaming
vue
<SidekickCollapsibleThoughtStreaming :steps="liveThoughts" :duration="0" />Props:
steps:ThinkingStep[]- Array of thought stepsduration:number- Duration when completed
Step Interface:
typescript
interface ThinkingStep {
message: string // Note: 'message' not 'text'
completed: boolean // Last step should be false
event?: string
agent_name?: string
tool_details?: Record<string, unknown>
}Common Types
ChatMessage
typescript
interface ChatMessage {
id: string
sender: 'user' | 'bot' | 'ticket'
text: string
isError?: boolean
thoughtSteps?: ThoughtStep[]
thinkingDuration?: number
kbSources?: KBSource[]
analyticsId?: string
}ThoughtStep (Completed)
typescript
interface ThoughtStep {
text: string // For SidekickCollapsibleThought
completed: boolean
event?: string
agent_name?: string
tool_details?: Record<string, unknown>
}ThoughtStep (Streaming)
typescript
interface ThoughtStep {
message: string // For SidekickCollapsibleThoughtStreaming
completed: boolean
event?: string
agent_name?: string
tool_details?: Record<string, unknown>
}KBSource
typescript
interface KBSource {
id: string
title: string
url?: string
snippet?: string
}Event Types
Common event types for thought steps:
tool_call- Function/tool invocationsobservation- Search results, observationsprocess- Processing, thinkingroute_to- Routing to agentsstart- Starting actions
Complete Example
vue
<template>
<div class="chat-container">
<!-- Messages -->
<div class="messages-area">
<SidekickMessages
:messages="messages"
:is-typing="isTyping"
:current-thoughts="currentThoughts"
:current-chunked-message="currentChunkedMessage"
:streaming-animating="streamingAnimating"
/>
</div>
<!-- Input -->
<div class="input-area">
<SidekickChatInput
placeholder="Ask me anything..."
:disabled="isLoading"
@submit="handleSubmit"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { SidekickMessages, SidekickChatInput, type ChatMessage } from '@sprout_ai_labs/sidekick'
const messages = ref<ChatMessage[]>([])
const isTyping = ref(false)
const currentThoughts = ref([])
const currentChunkedMessage = ref('')
const streamingAnimating = ref(false)
const isLoading = ref(false)
async function handleSubmit(message: string) {
// Add user message
messages.value.push({
id: Date.now().toString(),
sender: 'user',
text: message,
})
// Start streaming
isTyping.value = true
streamingAnimating.value = true
isLoading.value = true
try {
await sendToAPI(message)
} finally {
isTyping.value = false
streamingAnimating.value = false
isLoading.value = false
}
}
async function sendToAPI(message: string) {
// Your API implementation here
}
</script>
<style scoped>
.chat-container {
display: flex;
flex-direction: column;
height: 100vh;
}
.messages-area {
flex: 1;
overflow-y: auto;
padding: 1rem;
}
.input-area {
border-top: 1px solid #e5e7eb;
padding: 1rem;
}
</style>Store API (Unified Components)
typescript
import { useChatStore } from '@sprout_ai_labs/sidekick'
const chatStore = useChatStore()
// Authentication
chatStore.setToken('your-token')
chatStore.clearToken()
// Send message
chatStore.sendMessage('Hello')
// Access state
chatStore.messages // ChatMessage[]
chatStore.isTyping // boolean
chatStore.isConnected // boolean
chatStore.user // AuthUser | null
// Clear conversation
chatStore.clearConversation()Styling
CSS Import
typescript
import '@sprout_ai_labs/sidekick/dist/sprout-sidekick.css'Key CSS Classes
css
/* Messages */
.scp-messages
.scp-message-bubble
.scp-user-message-text
.scp-ai-message-text
/* Input */
.sidekick-chat-input-container
.sidekick-chat-input-editable
/* Thoughts */
.collapsible-thought
.thought-header
.thought-stepsCustom Styling Example
css
/* Override message colors */
.scp-user-message-text {
background: #your-brand-color !important;
}
/* Override input styling */
.sidekick-chat-input-editable {
font-size: 16px;
padding: 12px;
}Plugin Configuration
typescript
app.use(SproutSidekick, {
mode: 'PROD', // Required: 'QA' | 'PROD'
appName: 'My App', // Required: Your app name
skipDesignSystem: false, // Optional: Skip design system
baseUrl: 'https://...', // Optional: Custom backend URL
deviceSource: 'web', // Optional: 'mobile' | 'web'
})