SDK Reference
Complete API reference for the Coherence JavaScript SDK.
Configuration
The SDK configuration comes from two sources:
- Backend Configuration: Set in your Coherence dashboard and automatically loaded by the SDK
- Frontend Configuration: Passed to
Coherence.init()
and used as fallback for any settings not configured in the backend
Backend Configuration
The following settings can be configured in your Coherence dashboard and will automatically override frontend defaults:
Setting | Type | Description |
---|---|---|
name |
string |
Assistant name shown in modal header (default: "Ask AI") |
placeholderText |
string |
Help text shown in modal input (default: "How can I help you today?") |
triggerConfig.showTriggerButton |
boolean |
Whether to show floating trigger button (default: true ) |
triggerConfig.triggerText |
string |
Text displayed on trigger button (default: "Open Chat") |
triggerConfig.triggerClassName |
string |
CSS class for custom trigger styling (default: "") |
triggerConfig.position |
string |
Trigger position: 'bottom-right' , 'bottom-left' , 'top-right' , 'top-left' (default: "bottom-right") |
triggerConfig.containerRef |
string |
Container reference for modal mounting (optional) |
threadSuggestions |
string[] |
List of suggested conversation starters (default: [] ) |
theme |
object |
Open-ended theme object for frontend customization (default: {} ) |
Benefits of Backend Configuration: - Centralized configuration management - No code changes required for UI updates - Consistent settings across all SDK instances - Easy A/B testing and feature toggles
Initialization
Coherence.init(config)
Initializes the Coherence SDK with your configuration.
Parameters:
interface InitConfig {
// OAuth Mode Configuration
oauth?: {
enabled: boolean;
appId: string;
getToken: () => Promise<string> | string;
getHeaders?: () => Promise<Record<string, string>> | Record<string, string>;
cookieNames?: string[];
onTokenRefresh?: (result: TokenRefreshResult) => void;
tokenHeaderName?: string;
};
// Backend SDK Mode Configuration
// this is the route in your backend you added the Coherence interation to
chatEndpoint?: string;
// Optional: your app's backend URL if different from frontend host
appBackendUrl?: string;
// UI Configuration (Frontend Fallbacks)
// Note: These are overridden by backend configuration when
// available (from the Coherence dashboard)
name?: string;
placeholderText?: string;
threadSuggestions?: string[];
triggerConfig?: {
triggerText?: string;
triggerClassName?: string;
showTriggerButton?: boolean;
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
headless?: boolean;
containerRef?: string;
};
// Theme Configuration (also overriden by dashboard-set options)
theme?: {
primaryColor?: string;
backgroundColor?: string;
textColor?: string;
borderRadius?: string;
fontFamily?: string;
customStyles?: string;
};
// Advanced Options
extraContext?: Record<string, any>;
getExtraContext?: () => Promise<Record<string, any>> | Record<string, any>;
debug?: boolean;
onError?: (error: CoherenceError) => void;
onConnectionChange?: (connected: boolean) => void;
}
Returns: Promise<void>
Example:
await Coherence.init({
oauth: {
enabled: true,
appId: 'app_123',
getToken: async () => {
const session = await getAuthSession();
return session.token;
}
}
});
Core Methods
Coherence.show()
Shows the chat modal interface.
Returns: void
Example:
Coherence.show();
Coherence.hide()
Hides the chat modal interface.
Returns: void
Example:
Coherence.hide();
Coherence.toggle()
Toggles the chat modal visibility.
Returns: void
Example:
Coherence.toggle();
Coherence.isVisible()
Returns whether the chat modal is currently visible.
Returns: boolean
Example:
if (Coherence.isVisible()) {
console.log('Chat is open');
}
Coherence.sendMessage(message, options)
Sends a message programmatically to the chat interface.
Parameters:
- message: string | MessageContent[]
- The message to send
- options?: SendMessageOptions
- Additional options
interface SendMessageOptions {
autoShow?: boolean; // Whether to show chat modal (default: true)
role?: 'user' | 'assistant'; // Message role (default: 'user')
extraContext?: Record<string, any>; // Additional context for this message
}
Returns: Promise<{success: boolean}>
Example:
// Send a simple text message
await Coherence.sendMessage('Hello, how can you help me?');
// Send message with context without showing modal
await Coherence.sendMessage('Show me my analytics', {
autoShow: false,
extraContext: {
currentPage: 'dashboard',
selectedMetrics: ['revenue', 'users']
}
});
// Send complex content
await Coherence.sendMessage([
{ type: 'text', text: 'Check this image:' },
{ type: 'image', url: 'https://example.com/chart.png' }
]);
Coherence.getInstance()
Returns the SDK instance for advanced usage.
Returns: CoherenceInstance
Example:
const instance = Coherence.getInstance();
Coherence.destroy()
Destroys the SDK instance and cleans up resources.
Returns: void
Example:
Coherence.destroy();
Instance Methods
Access these methods via Coherence.getInstance()
:
updateConfig(config)
Updates the SDK configuration dynamically.
Parameters: Partial InitConfig
object
Returns: void
Example:
const instance = Coherence.getInstance();
instance.updateConfig({
triggerText: 'Need Help?',
theme: {
primaryColor: '#10b981'
}
});
getStore()
Returns the conversation store for custom UI implementations.
Returns: ConversationStore
Example:
const store = Coherence.getInstance().getStore();
Conversation Store API
Access via Coherence.getInstance().getStore()
:
State Management
getState()
Returns the current state of the conversation store.
Returns:
interface StoreState {
conversations: Conversation[];
activeConversation: Conversation | null;
messages: Message[];
loading: boolean;
error: Error | null;
user: User | null;
}
Example:
const state = store.getState();
console.log('Active conversation:', state.activeConversation);
subscribe(listener)
Subscribes to state changes.
Parameters:
- listener: (state: StoreState) => void
- Function called on state changes
Returns: () => void
- Unsubscribe function
Example:
const unsubscribe = store.subscribe((state) => {
console.log('New state:', state);
});
// Later: unsubscribe();
Conversation Management
getConversations()
Fetches all conversations for the current user.
Returns: Promise<Conversation[]>
Example:
const conversations = await store.getConversations();
createConversation(options)
Creates a new conversation.
Parameters:
interface CreateConversationOptions {
title?: string;
metadata?: Record<string, any>;
}
Returns: Promise<Conversation>
Example:
const conversation = await store.createConversation({
title: 'Product Support'
});
setActiveConversation(conversationId)
Sets the active conversation and loads its messages.
Parameters:
- conversationId: string
- The conversation ID
Returns: Promise<void>
Example:
await store.setActiveConversation('conv_123');
updateConversation(conversationId, updates)
Updates a conversation's properties.
Parameters:
- conversationId: string
- The conversation ID
- updates: Partial<Conversation>
- Properties to update
Returns: Promise<Conversation>
Example:
await store.updateConversation('conv_123', {
title: 'Resolved: Product Issue',
status: 'archived'
});
deleteConversation(conversationId)
Deletes a conversation.
Parameters:
- conversationId: string
- The conversation ID
Returns: Promise<void>
Example:
await store.deleteConversation('conv_123');
Message Management
sendMessage(options)
Sends a message in the active conversation.
Parameters:
interface SendMessageOptions {
content: MessageContent[];
conversationId?: string; // Defaults to active conversation
metadata?: Record<string, any>;
extraContext?: Record<string, any>; // Additional context for AI
}
interface MessageContent {
type: 'text' | 'image' | 'file';
text?: string;
url?: string;
name?: string;
size?: number;
}
Returns: Promise<Message>
Example:
// Send text message
await store.sendMessage({
content: [{ type: 'text', text: 'Hello!' }]
});
// Send message with image
await store.sendMessage({
content: [
{ type: 'text', text: 'Check this out:' },
{ type: 'image', url: 'https://example.com/image.jpg' }
]
});
// Send message with additional context for the AI
await store.sendMessage({
content: [{ type: 'text', text: 'Help me analyze this data' }],
extraContext: {
currentPage: 'analytics',
selectedMetrics: ['revenue', 'users'],
timeRange: 'last-30-days'
}
});
getMessages(conversationId)
Gets all messages for a conversation.
Parameters:
- conversationId: string
- The conversation ID
Returns: Promise<Message[]>
Example:
const messages = await store.getMessages('conv_123');
streamResponse(messageId)
Streams the AI response for a message.
Parameters:
- messageId: string
- The user message ID
Returns: EventSource
- Server-sent events stream
Example:
const stream = store.streamResponse('msg_123');
stream.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
console.log('Partial response:', data);
});
stream.addEventListener('error', (error) => {
console.error('Stream error:', error);
});
File Uploads
uploadFile(file)
Uploads a file for use in messages.
Parameters:
- file: File
- The file to upload
Returns: Promise<UploadedFile>
Example:
const input = document.getElementById('file-input');
const file = input.files[0];
const uploaded = await store.uploadFile(file);
console.log('File URL:', uploaded.url);
Data Types
Conversation
interface Conversation {
id: string;
title: string;
status: 'regular' | 'archived';
created_at: string;
updated_at: string;
last_message_at: string;
metadata?: Record<string, any>;
}
Message
interface Message {
id: string;
conversation_id: string;
role: 'user' | 'assistant';
content: MessageContent[];
created_at: string;
metadata?: Record<string, any>;
}
User
interface User {
id: string;
app_id: string;
created_at: string;
metadata?: Record<string, any>;
}
Error Types
interface CoherenceError {
type: 'AUTH_FAILED' | 'NETWORK_ERROR' | 'RATE_LIMIT' | 'VALIDATION_ERROR' | 'UNKNOWN';
message: string;
details?: any;
}
Events
The SDK emits various events you can listen to:
Window Events
// Chat opened
window.addEventListener('coherence:open', (event) => {
console.log('Chat opened');
});
// Chat closed
window.addEventListener('coherence:close', (event) => {
console.log('Chat closed');
});
// New message received
window.addEventListener('coherence:message', (event) => {
console.log('New message:', event.detail);
});
// Error occurred
window.addEventListener('coherence:error', (event) => {
console.error('Error:', event.detail);
});
Advanced Usage
Extra Context for AI
Provide additional context to help the AI understand the user's current situation and give more relevant responses.
Static Context (Initialization)
await Coherence.init({
oauth: {
enabled: true,
appId: 'app_123',
getToken: async () => getToken()
},
// Static context applied to all conversations
extraContext: {
userRole: 'admin',
permissions: ['read', 'write', 'delete'],
currentWorkspace: 'acme-corp'
}
});
Dynamic Context (Callback)
For context that changes based on the current state of your application, use the getExtraContext
callback. This function is called automatically for every message in both the default UI and when using sendMessage()
without explicit context:
await Coherence.init({
oauth: {
enabled: true,
appId: 'app_123',
getToken: async () => getToken()
},
// Dynamic context callback - called for every message
getExtraContext: async () => {
// Fetch current application state
const currentUser = await getCurrentUser();
const currentPage = window.location.pathname;
const selectedItems = getSelectedItems();
return {
userRole: currentUser.role,
currentPage: currentPage,
selectedItems: selectedItems,
timestamp: new Date().toISOString(),
// Any other dynamic context
userPreferences: await getUserPreferences()
};
},
// Static fallback context
extraContext: {
appVersion: '1.0.0',
environment: 'production'
}
});
When is getExtraContext
called?
- Default UI: Every time a user types a message and presses send
sendMessage()
without context: When callingsendMessage()
without providingextraContext
in options- Error handling: If the callback throws an error, it falls back to static context
Benefits of dynamic context:
- Real-time context based on current app state
- No need to manually update context when user navigates or changes selection
- Async support for API calls or complex state retrieval
- Automatic fallback to static context if callback fails
Per-Message Context
const store = Coherence.getInstance().getStore();
// Context for specific message
await store.sendMessage({
content: [{ type: 'text', text: 'Show me the quarterly report' }],
extraContext: {
quarter: 'Q3-2024',
reportType: 'financial',
department: 'sales'
}
});
Context Precedence and Merging
When multiple context sources are provided, they are merged with the following precedence (higher precedence overwrites lower):
- Per-message context (highest precedence) - provided via
sendMessage({ extraContext: ... })
- Dynamic context - returned by
getExtraContext()
callback - Static context (lowest precedence) - provided via
extraContext
in initialization
// Static context from init
const staticContext = { userRole: 'admin', theme: 'dark', appVersion: '1.0.0' };
// Dynamic context from callback
const dynamicContext = { theme: 'light', currentPage: 'dashboard', timestamp: '2024-01-01' };
// Message context
const messageContext = { currentPage: 'analytics', customData: 'special' };
// Final context sent to AI:
// {
// userRole: 'admin', // from static (not overridden)
// theme: 'light', // from dynamic (overrides static)
// appVersion: '1.0.0', // from static (not overridden)
// currentPage: 'analytics', // from message (overrides dynamic)
// timestamp: '2024-01-01', // from dynamic (not overridden)
// customData: 'special' // from message (new)
// }
Important Notes:
- The getExtraContext
callback is called for every message, allowing truly dynamic context
- Dynamic context can be async and perform API calls or complex calculations
- If getExtraContext
throws an error, it falls back to static context
- All context merging is shallow (nested objects are not deep merged)
Custom Authentication Headers
await Coherence.init({
oauth: {
enabled: true,
appId: 'app_123',
getToken: async () => {
return localStorage.getItem('token');
},
getHeaders: async () => {
// These headers are sent with every message request
return {
'X-API-Key': await getApiKey(),
'X-User-Context': JSON.stringify({
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
locale: navigator.language
})
};
}
}
});
Cookie Management
await Coherence.init({
oauth: {
enabled: true,
appId: 'app_123',
getToken: async () => getToken(),
cookieNames: ['sessionId', 'workspace', 'preferences'],
// Cookies with these names will be automatically included
// in message requests to your API
}
});
Error Recovery
await Coherence.init({
oauth: {
enabled: true,
appId: 'app_123',
getToken: async () => getToken(),
onTokenRefresh: (result) => {
if (result.error) {
// Token refresh failed
if (result.error.type === 'AUTH_FAILED') {
// Redirect to login
window.location.href = '/login';
}
} else {
// Token refreshed successfully
console.log('Token refreshed');
}
}
},
onError: (error) => {
// Global error handler
switch(error.type) {
case 'NETWORK_ERROR':
showOfflineMessage();
break;
case 'RATE_LIMIT':
showRateLimitMessage();
break;
default:
console.error('Coherence error:', error);
}
}
});
Headless Mode
// Initialize without UI
await Coherence.init({
modalConfig: {
headless: true
},
oauth: {
enabled: true,
appId: 'app_123',
getToken: async () => getToken()
}
});
// Build your own UI using the store
const store = Coherence.getInstance().getStore();
// Example: Custom React hook
function useCoherence() {
const [state, setState] = useState(store.getState());
useEffect(() => {
return store.subscribe(setState);
}, []);
return {
...state,
sendMessage: (text) => store.sendMessage({
content: [{ type: 'text', text }]
})
};
}
Browser Support
- Chrome/Edge: Latest 2 versions
- Firefox: Latest 2 versions
- Safari: Latest 2 versions
- Mobile browsers: iOS Safari 14+, Chrome Android
Performance
- Initial bundle size: ~50KB gzipped
- Lazy loads additional features as needed
- Automatic connection management
- Request debouncing and batching
- Efficient DOM updates
Security
- All data transmitted over HTTPS
- JWT tokens expire after 1 hour
- Automatic token refresh
- XSS protection built-in
- Content Security Policy compatible