@agentman/chat-widget
Version:
Agentman Chat Widget for easy integration with web applications
343 lines (342 loc) • 10.8 kB
TypeScript
export type ChatVariant = 'input-bar-only' | 'corner' | 'centered' | 'input-bar-sheet';
/**
* AgentClosedView modes - How to display the widget when closed (for corner variant only)
* - toggle-only: Just the chat button, no prompts shown externally
* - floating-prompts: Traditional floating bubbles with prompts
* - welcome-card: Glassmorphic card with prompts inside
* - input-bar-only: Modern AI search bar at bottom of screen with typewriter effect
*/
export type ClosedViewMode = 'toggle-only' | 'floating-prompts' | 'welcome-card' | 'input-bar-only';
/**
* API configuration for connecting to Agentman backend
*/
export interface ApiConfig {
/** API endpoint URL */
url: string;
/** Agent authentication token */
token: string;
}
/**
* Prompt rule for URL-based dynamic prompts
*/
export interface PromptRule {
/** URL pattern to match against window.location.pathname */
urlPattern: string;
/** How to match the URL pattern */
matchType: 'exact' | 'startsWith' | 'contains';
/** Prompts to display when this rule matches */
prompts: [string?, string?, string?];
}
/**
* Content configuration - user-facing text (v3.0+)
*/
export interface ContentConfig {
/** Widget title shown in header */
title?: string;
/** Placeholder text for input field */
placeholder?: string;
/** Initial message displayed by the agent */
initialMessage?: string;
/** Input bar brand text (for input-bar-sheet/input-bar-only variants) */
inputBarBrandText?: string;
/** Toggle button text (for corner variant) */
toggleText?: string;
/** Welcome message and prompt suggestions */
messagePrompts?: {
/** @deprecated Use agentClosedView instead to control visibility */
show?: boolean;
/** Welcome message text */
welcome_message?: string;
/** Up to 3 prompt suggestions (static - used when no rules match) */
prompts?: [string?, string?, string?];
/** Dynamic prompt rules based on URL (v3.1+) */
rules?: PromptRule[];
/** Default prompts when no rules match */
default?: [string?, string?, string?];
};
}
/**
* Assets configuration for logos and icons (v3.0+)
*/
export interface AssetsConfig {
/** URL to image or SVG string for the main logo */
logo: string;
/** URL to image or SVG string for the header logo */
headerLogo: string;
/** Custom icon overrides */
icons?: {
close?: string;
send?: string;
minimize?: string;
maximize?: string;
expand?: string;
collapse?: string;
reduce?: string;
};
}
/**
* Layout configuration for positioning and dimensions (v3.0+)
*/
export interface LayoutConfig {
/** Desktop-specific layout settings */
desktop?: {
/** Widget position on screen (only for corner variant) */
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
/** Initial width of widget */
width?: string;
/** Initial height of widget */
height?: string;
/** Whether widget opens automatically on load */
initiallyOpen?: boolean;
};
/** Mobile-specific layout settings */
mobile?: {
/** Height on mobile devices (e.g., '80vh', '100vh') */
height?: string;
/** Maximum height on mobile devices */
maxHeight?: string;
};
/** Whether to show collapsed sheet bar at bottom (input-bar-sheet variant only, default: true) */
showCollapsedSheet?: boolean;
}
/**
* Theme color configuration (v3.0+)
*/
export interface ThemeColors {
text: string;
background: string;
button: string;
buttonText: string;
agentText: string;
userText: string;
headerBackground?: string;
headerText?: string;
disclaimerBackground?: string;
disclaimerText?: string;
disclaimerBorder?: string;
toggleBackground: string;
toggleText: string;
toggleIcon: string;
inputBarBrandBackground?: string;
inputBarBrandBackgroundHover?: string;
inputBarBrandText?: string;
inputBarLogoBackground?: string;
inputBarLogoIcon?: string;
inputBarButtonBackground?: string;
inputBarButtonIcon?: string;
inputBarGlow?: string;
inputBarSheetBackground?: string;
inputBarTypewriterColor?: string;
}
export interface ChatTheme {
colors: ThemeColors;
}
export interface ChatAssets {
/** URL to image or SVG string for the main logo */
logo: string;
/** URL to image or SVG string for the header logo */
headerLogo: string;
}
export interface ChatIcons {
closeIcon?: string;
sendIcon?: string;
minimizeIcon?: string;
maximizeIcon?: string;
expandIcon?: string;
collapseIcon?: string;
reduceIcon?: string;
}
/**
* Features configuration for optional functionality (v3.0+)
*/
export interface FeaturesConfig {
/** Enable/disable file attachments (default: true) */
attachments?: boolean;
/** Conversation persistence configuration */
persistence?: PersistenceConfig;
/** Streaming responses configuration */
streaming?: {
/** Enable streaming responses (default: true) */
enabled?: boolean;
/** Prefer streaming when available */
preferStreaming?: boolean;
/** Fallback to non-streaming on error */
fallbackToNonStreaming?: boolean;
};
/** AI disclaimer/footer message */
disclaimer?: {
/** Enable disclaimer display */
enabled: boolean;
/** Disclaimer message text */
message: string;
/** Optional link text */
linkText?: string;
/** Optional link URL */
linkUrl?: string;
};
/** Sticky element detection configuration */
stickyDetection?: {
/** Enable automatic detection of sticky elements (default: false) */
enabled?: boolean;
/** Additional selectors to watch for sticky behavior */
customSelectors?: string[];
};
}
export interface ChatConfig {
/**
* API configuration (v3.0+)
*/
api: ApiConfig;
/**
* Assets configuration (v3.0+)
*/
assets: AssetsConfig;
/**
* Layout configuration (v3.0+)
*/
layout?: LayoutConfig;
/**
* Content configuration - user-facing text (v3.0+)
*/
content?: ContentConfig;
/**
* Features configuration (v3.0+)
*/
features?: FeaturesConfig;
variant: 'input-bar-only' | 'corner' | 'centered' | 'input-bar-sheet' | 'inline' | 'sheet';
containerId: string;
theme?: Partial<ChatTheme>;
/** Custom toggle button colors from WordPress settings */
toggleStyle?: {
/** Background color for the toggle button */
backgroundColor?: string;
/** Text color for the toggle button */
textColor?: string;
/** Icon color for the toggle button */
iconColor?: string;
};
/** Client metadata to send with API requests */
clientMetadata?: Partial<ClientMetadata>;
/** Enable automatic client metadata collection */
collectClientMetadata?: boolean;
/** Enable IP address collection (requires external API call) */
collectIPAddress?: boolean;
/** Debug configuration for development and troubleshooting */
debug?: boolean | DebugConfig;
/** Markdown configuration for customizing marked.js loading and options */
markdownConfig?: {
cdnUrls?: string[];
timeout?: number;
markedOptions?: {
gfm?: boolean;
breaks?: boolean;
headerIds?: boolean;
mangle?: boolean;
pedantic?: boolean;
smartLists?: boolean;
smartypants?: boolean;
};
};
/**
* AgentClosedView mode - How to display the widget when closed
* - 'toggle-only': Just the chat button, no prompts shown externally
* - 'floating-prompts': Traditional floating bubbles with prompts
* - 'welcome-card': Glassmorphic card with prompts inside
*
* If not specified, falls back to legacy messagePrompts.show logic
*/
agentClosedView?: ClosedViewMode;
}
export interface DebugConfig {
/** Enable debug logging */
enabled: boolean;
/** Log levels to include */
logLevel?: 'error' | 'warn' | 'info' | 'debug' | 'verbose';
/** Include timestamps in logs */
timestamps?: boolean;
/** Log to console */
console?: boolean;
/** Custom logger function */
logger?: (level: string, message: string, data?: any) => void;
}
export interface FileAttachment {
file_id: string;
filename: string;
content_type: string;
file_type: 'image' | 'document' | 'audio' | 'video' | 'text' | 'data';
size_bytes: number;
url?: string;
upload_status: 'pending' | 'uploading' | 'success' | 'error';
upload_progress?: number;
error_message?: string;
created_at?: string;
expires_at?: string;
}
export interface Message {
id: string;
sender: 'user' | 'agent';
content: string;
timestamp: string;
type?: 'text' | 'html' | 'custom' | 'svg' | 'tool' | 'system';
data?: any;
attachments?: FileAttachment[];
isStreaming?: boolean;
}
export interface ChatState {
isOpen: boolean;
isExpanded: boolean;
isInitialized: boolean;
isSending: boolean;
messages: Message[];
error?: string;
pendingAttachments: FileAttachment[];
isUploadingFiles: boolean;
currentView: 'welcome' | 'conversation';
hasStartedConversation: boolean;
isTransitioning?: boolean;
}
export interface APIResponse {
id: string;
type: 'ai' | 'user';
content: string;
}
export interface PersistenceConfig {
enabled?: boolean;
days?: number;
key?: string;
}
export interface AgentMetadata {
supported_mime_types?: string[];
supports_attachments?: boolean;
model_name?: string;
model_version?: string;
capabilities?: string[];
max_file_size?: number;
max_attachments?: number;
[key: string]: any;
}
export interface ClientMetadata {
user_id?: string | number;
user_email_address?: string;
device_id?: string;
browser_language?: string;
browser_device?: string;
browser_timezone?: string;
ip_address?: string;
session_id?: string;
user_agent?: string;
referer_url?: string;
page_url?: string;
geo_location?: string;
is_authenticated?: boolean;
custom_tags?: Record<string, any>;
}
/**
* Welcome card state stored in WeakMap
*/
export interface WelcomeCardState {
originalToggleParent: HTMLElement;
originalToggleOnClick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;
closeButtonHandler: (e: Event) => void;
keyboardHandler: (e: KeyboardEvent) => void;
}