import type { SessionStorageConfig } from './CyberneticSessionStorage.js'; /** * Configuration loading options */ export interface ConfigOptions { /** Throw error if API key is missing (default: true) */ throwOnMissingKey?: boolean; } /** * Configuration source (for debugging) */ export type ConfigSource = 'props' | 'env' | 'window' | 'data-attr' | 'vite'; /** * Transport mode for chat communication * - 'auto': Use WebSocket if wsUrl available, fall back to REST+SSE (default) * - 'websocket': Force WebSocket transport (fails if unavailable) * - 'rest': Force REST+SSE transport (current behavior) */ export type TransportMode = 'auto' | 'websocket' | 'rest'; /** * WebSocket transport connection state */ export type TransportState = 'disconnected' | 'connecting' | 'connected' | 'error'; /** * WebSocket transport configuration options */ export interface WebSocketOptions { /** Max reconnection attempts before giving up (default: 3) */ maxReconnectAttempts?: number; /** Initial reconnect delay in ms, doubles each attempt (default: 1000) */ reconnectDelay?: number; /** Connection timeout in ms (default: 10000) */ connectionTimeout?: number; } /** * Configuration for CyberneticClient */ export interface CyberneticConfig { /** Backend API URL (REST endpoint for status, health, docs, and fallback chat) */ apiUrl: string; /** API key for authentication */ apiKey: string; /** WebSocket URL for streaming chat (auto-detected for SaaS domains if not set) */ wsUrl?: string; /** * Transport mode for chat. * - 'auto': Use WebSocket if wsUrl available/detected, fall back to REST+SSE (default) * - 'websocket': Force WebSocket (fails if unavailable) * - 'rest': Force REST+SSE (ignores wsUrl) */ transport?: TransportMode; /** WebSocket transport options (reconnection, timeouts) */ websocket?: WebSocketOptions; /** License key (JWT token) for AsterMind licensing */ licenseKey?: string; /** Override environment detection for license enforcement ('development' = soft, 'production' = hard) */ environment?: 'development' | 'production'; /** Where the config was loaded from (for debugging) */ _source?: ConfigSource; /** Fallback/offline configuration */ fallback?: { /** Enable offline fallback (default: true) */ enabled?: boolean; /** Cache max age in milliseconds (default: 24 hours) */ cacheMaxAge?: number; /** Sync documents on connect (default: true) */ cacheOnConnect?: boolean; /** Storage type (default: 'indexeddb') */ cacheStorage?: 'indexeddb' | 'localstorage'; }; /** Retry configuration */ retry?: { /** Max retries before fallback (default: 2) */ maxRetries?: number; /** Initial delay in ms (default: 1000) */ initialDelay?: number; /** Use exponential backoff (default: true) */ exponentialBackoff?: boolean; }; /** Event callbacks */ onStatusChange?: (status: ConnectionStatus) => void; onError?: (error: CyberneticError) => void; /** Optional agentic capabilities configuration (requires importing CyberneticAgent) */ agentic?: AgenticConfig; /** Offline vector export configuration */ offline?: OfflineConfig; /** Sitemap configuration for agentic navigation */ sitemap?: SiteMapConfig; /** Sources display and handling configuration */ sources?: SourcesConfig; /** Session persistence configuration (default: enabled with 30-minute TTL) */ session?: SessionStorageConfig; /** Sales Agent mode configuration (enables /api/external/sales/* endpoints) */ salesMode?: SalesConfig; /** Enable debug logging to console (default: false) */ debug?: boolean; } /** * Site map entry for agentic navigation */ export interface AgenticSiteMapEntry { /** URL path pattern */ path: string; /** Display name */ name: string; /** Description for intent matching */ description?: string; /** Allowed query/path parameters */ params?: Record; /** Whether path has dynamic segments like :id */ dynamicParams?: boolean; /** Aliases for fuzzy matching */ aliases?: string[]; } /** * Form field configuration for agentic form filling */ export interface AgenticFormFieldConfig { /** CSS selector for the field */ selector: string; /** Field name for intent matching */ name: string; /** Aliases for fuzzy matching */ aliases?: string[]; } /** * Modal trigger configuration for agentic modal handling */ export interface AgenticModalTriggerConfig { /** Modal identifier */ id: string; /** CSS selector for trigger element */ trigger: string; /** Aliases for fuzzy matching */ aliases?: string[]; } /** * Result of an agentic action execution */ export interface AgenticActionResult { /** Whether action succeeded */ success: boolean; /** Result message */ message: string; /** Error details if failed */ error?: string; } /** * Agentic capabilities configuration * Only active when CyberneticAgent is imported AND enabled */ export interface AgenticConfig { /** Enable agentic DOM interactions (default: false) */ enabled: boolean; /** Confidence threshold for action execution (default: 0.8) */ confidenceThreshold?: number; /** Site map for navigation - defines which pages the agent can navigate to (legacy) */ siteMap?: AgenticSiteMapEntry[]; /** Multi-source sitemap configuration for automatic route discovery */ siteMapConfig?: MultiSourceSiteMapConfig; /** Form field configurations for form filling actions */ forms?: Record; /** Modal trigger configurations for modal opening actions */ modals?: Record; /** Custom action callbacks - registered actions the agent can execute */ customActions?: Record Promise>; /** Allowed DOM actions */ allowedActions?: ('click' | 'fill' | 'scroll' | 'navigate' | 'select')[]; /** Require user confirmation before actions (default: true) */ confirmActions?: boolean; /** * Alias for confirmActions - require user confirmation before actions * Use this or confirmActions, not both */ requireConfirmation?: boolean; /** Maximum actions per conversation turn (default: 5) */ maxActionsPerTurn?: number; /** CSS selectors to never interact with */ blockedSelectors?: string[]; /** Only allow actions within these selectors */ allowedSelectors?: string[]; } /** * Connection status */ export type ConnectionStatus = 'online' | 'offline' | 'connecting' | 'error'; /** * Confidence level of response */ export type ConfidenceLevel = 'high' | 'medium' | 'low' | 'none'; /** * Source document from RAG */ export interface Source { title: string; snippet: string; relevance: number; documentId?: string; /** Full content for summary view (offline capable) */ fullContent?: string; /** Backend download endpoint URL */ downloadUrl?: string; /** Display name for the source document */ documentName?: string; /** Type of source */ sourceType?: 'document' | 'conversation' | 'cached'; /** Chunk ID for specific content reference */ chunkId?: string; } /** * Configuration for source display and handling */ export interface SourcesConfig { /** Include sources in responses (default: true) */ enabled?: boolean; /** Show summary/eye icon in UI (default: true) */ showSummary?: boolean; /** Show download button in UI - only works online (default: true) */ showDownload?: boolean; /** Include fullContent for offline summary capability (default: false) */ includeFullContent?: boolean; /** Max sources to return (default: 5) */ maxSources?: number; } /** * Response from CyberneticClient * Always returned, never throws */ export interface CyberneticResponse { /** The response text */ reply: string; /** Confidence level of the response */ confidence: ConfidenceLevel; /** Source documents used */ sources: Source[]; /** Whether response came from offline fallback */ offline: boolean; /** Session ID for conversation continuity */ sessionId?: string; /** Backend message ID for prompt/context retrieval */ messageId?: string; /** Seconds until retry is suggested (only on failures) */ retryAfter?: number; /** Why confidence is reduced (for debugging) */ degradedReason?: string; } /** * Request options for ask() */ export interface AskOptions { /** Session ID for conversation continuity */ sessionId?: string; /** Context metadata */ context?: { currentPage?: string; pageTitle?: string; }; /** Skip offline fallback for this request */ skipFallback?: boolean; } /** * Streaming callback for SSE responses */ export interface StreamCallbacks { onToken?: (token: string) => void; onSources?: (sources: Source[]) => void; onComplete?: (response: CyberneticResponse) => void; onError?: (error: CyberneticError) => void; } /** * Cached document for offline RAG */ export interface CachedDocument { id: string; title: string; content?: string; updatedAt: string; embedding?: number[]; } /** * Cache status */ export interface CacheStatus { documentCount: number; lastSyncAt: string | null; cacheSize: number; isStale: boolean; } /** * Error type for Cybernetic operations */ export interface CyberneticError { code: 'NETWORK_ERROR' | 'AUTH_ERROR' | 'RATE_LIMIT' | 'SERVER_ERROR' | 'CACHE_ERROR' | 'LOCAL_RAG_ERROR' | 'WS_ERROR'; message: string; retryAfter?: number; originalError?: Error; } /** * System-wide settings from server (ADR-200) */ export interface SystemSettings { /** Hours to retain cached data (default: 168 = 7 days) */ cacheRetentionHours: number; /** When true, clients should use cached data only */ maintenanceMode: boolean; /** Optional message to display during maintenance */ maintenanceMessage?: string; /** Force all clients to operate in offline mode */ forceOfflineClients: boolean; } /** * Offline vector export configuration * Enables loading pre-exported vectors for offline RAG functionality */ export interface OfflineConfig { /** Enable offline vector support (default: false) */ enabled?: boolean; /** URL to the exported vector JSON file */ vectorFileUrl?: string; /** Inline vector data (alternative to vectorFileUrl) */ vectorData?: OfflineVectorExport; /** Storage mode for cached vectors */ storageMode?: 'memory' | 'indexeddb' | 'hybrid'; /** Auto-refresh vectors when online (default: false) */ autoRefresh?: boolean; /** Cache max age in milliseconds (default: 7 days) */ cacheMaxAge?: number; /** Omega configuration for advanced offline RAG */ omega?: OfflineOmegaConfig; } /** * Omega-powered offline RAG configuration */ export interface OfflineOmegaConfig { /** Enable Omega-powered offline RAG */ enabled?: boolean; /** URL to pre-exported model JSON (SerializedModel format) */ modelUrl?: string; /** Inline model data */ modelData?: OmegaSerializedModel; /** Reranking configuration */ reranking?: { enabled?: boolean; topK?: number; diversityWeight?: number; }; } /** * Omega serialized model format from @astermind/astermind-community */ export interface OmegaSerializedModel { version: string; createdAt: string; config: { embeddingDim: number; numLandmarks: number; gamma: number; }; vocabulary: Record; idf: Record; tfidfDocs: Array>; documents: Array<{ id: string; content: string; metadata?: Record; }>; landmarkMat: number[][]; ridgeWeights?: number[][]; } /** * Offline vector export format * Generated by backend export API */ export interface OfflineVectorExport { /** Export format version */ version: string; /** Export type: general, tenant, or combined */ type: 'general' | 'tenant' | 'combined'; /** Export metadata */ meta: { exportedAt: string; documentCount: number; chunkCount: number; format: 'compact' | 'full'; tenantId?: string; tenantName?: string; }; /** Pre-computed TF-IDF index */ tfidfIndex: { idf: Record; totalDocuments: number; }; /** Document chunks with vectors */ documents: OfflineDocumentChunk[]; /** Category definitions for intent classification */ categories?: CategoryDefinition[]; /** Sitemap entries for navigation */ sitemap?: SiteMapEntry[]; } /** * Document chunk in offline export */ export interface OfflineDocumentChunk { id: string; documentId: string; title: string; content: string; tfidfVector: Array<[number, number]>; embedding?: number[]; metadata?: { section?: string; url?: string; keywords?: string[]; }; } /** * Category definition for intent classification */ export interface CategoryDefinition { id: string; name: string; keywords: string[]; weight?: number; } /** * Sitemap configuration for agentic navigation */ export interface SiteMapConfig { /** Enable sitemap-based navigation (default: true when sitemap provided) */ enabled?: boolean; /** URL to sitemap JSON file */ sitemapUrl?: string; /** Inline sitemap data */ sitemapData?: SiteMapEntry[]; /** Base URL for relative paths */ baseUrl?: string; } /** * Individual sitemap entry for navigation */ export interface SiteMapEntry { /** Page URL or path */ url: string; /** Page title */ title: string; /** Page description for matching */ description?: string; /** Keywords for intent matching */ keywords?: string[]; /** Priority for ranking (0-1) */ priority?: number; /** Last modification date */ lastmod?: string; /** Change frequency hint */ changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'; } /** * Source identifier for sitemap entries (for merge tracking and priority) */ export type SiteMapSource = 'props' | 'discovery' | 'backend' | 'export'; /** * Enhanced sitemap entry with source tracking metadata */ export interface EnhancedSiteMapEntry extends AgenticSiteMapEntry { /** Source of this entry for merge priority */ _source?: SiteMapSource; /** Priority score for sorting (higher = more important) */ _priority?: number; /** Timestamp when discovered/loaded */ _discoveredAt?: number; } /** * Route discovered from JavaScript framework router */ export interface DiscoveredRoute { /** Route path */ path: string; /** Route name (from router config or handle) */ name?: string; /** Route metadata (React Router handle, Vue meta, etc.) */ meta?: Record; /** Component name if available */ component?: string; /** Child routes */ children?: DiscoveredRoute[]; } /** * Framework auto-discovery configuration */ export interface FrameworkDiscoveryConfig { /** Enable auto-discovery (default: true) */ enabled?: boolean; /** Framework hint (auto-detected if not specified) */ framework?: 'react-router' | 'vue-router' | 'next' | 'angular' | 'generic'; /** Enable DOM fallback: scan navigation elements when router not detected (default: true) */ domFallback?: boolean; /** CSS selectors to scan for navigation links in DOM fallback */ navSelectors?: string[]; /** Paths to exclude from discovery (glob patterns like '/admin/*') */ excludePaths?: string[]; /** Transform discovered routes (e.g., add descriptions, filter) */ transformRoute?: (route: DiscoveredRoute) => AgenticSiteMapEntry | null; /** Maximum number of links to scan from DOM (default: 200) */ maxDomLinks?: number; /** Cache discovered routes in localStorage (default: true) */ cacheRoutes?: boolean; /** Cache TTL in milliseconds (default: 300000 = 5 minutes) */ cacheTtl?: number; } /** * Backend sitemap API configuration */ export interface BackendSiteMapConfig { /** Enable backend sitemap fetching (default: true if endpoint configured) */ enabled?: boolean; /** API endpoint URL or path (default: /api/external/sitemap) */ endpoint?: string; /** Cache TTL in milliseconds (default: 300000 = 5 minutes) */ cacheTtl?: number; /** Request tenant-specific sitemap using API key's tenant context (default: true) */ tenantScoped?: boolean; /** Include general (non-tenant) routes (default: true) */ includeGeneral?: boolean; /** Custom headers for the request */ headers?: Record; } /** * Merge strategy for combining sitemaps from multiple sources */ export interface SiteMapMergeConfig { /** Priority order for sources (first = highest priority, default: ['props', 'backend', 'discovery']) */ sourcePriority?: SiteMapSource[]; /** How to detect duplicate entries (default: 'path') */ deduplication?: 'path' | 'name' | 'both'; /** Keep non-conflicting fields from lower priority entries (default: true) */ keepNonConflicting?: boolean; } /** * Multi-source sitemap configuration * Enables automatic route discovery from multiple sources */ export interface MultiSourceSiteMapConfig { /** Static sitemap entries from props (Source 1 - highest priority) */ static?: AgenticSiteMapEntry[]; /** Framework auto-discovery configuration (Source 2) */ discovery?: FrameworkDiscoveryConfig; /** Backend API configuration (Source 3) */ backend?: BackendSiteMapConfig; /** Merge strategy configuration */ merge?: SiteMapMergeConfig; /** When to load sitemap: 'init' on widget load, 'first-query' on first agentic query, 'both' */ loadStrategy?: 'init' | 'first-query' | 'both'; /** Global base URL for relative paths */ baseUrl?: string; } /** * Widget configuration fetched from backend (GET /api/external/config) * Used by autoFetchConfig to dynamically configure widget persona and display settings. */ export interface ExternalConfigResponse { tenantName: string; persona: { type: string; name: string; displayLabel: string; icon: string; }; widget: { headerTitle: string; headerSubtitle: string; greeting: string; placeholder: string; theme: Record; showPoweredBy: boolean; position: string; }; } /** * Sales Agent mode configuration */ export interface SalesConfig { /** Enable sales mode (uses /api/external/sales/* endpoints) */ enabled: boolean; /** Visitor tracking configuration */ visitorTracking?: { /** Auto-track page views (default: true) */ autoPageView?: boolean; }; /** Proactive engagement configuration */ proactive?: { /** Enable proactive greeting popup */ enabled: boolean; /** Delay in milliseconds before showing popup (default: 15000) */ delayMs?: number; /** Enable exit intent detection */ exitIntent?: boolean; }; /** Lead capture form configuration */ leadCapture?: { /** Fields required before chat starts (e.g., ['email', 'first_name']) */ requiredBeforeChat?: string[]; /** Collect data progressively through conversation (default: true) */ progressiveMode?: boolean; }; } /** * Sales context returned alongside chat responses */ export interface SalesContext { visitorId: string | null; playbookId: string | null; currentStage: string | null; leadScore: number; leadCategory: 'hot' | 'warm' | 'cold'; suggestedQuestions: string[]; ctaButtons: CTAButton[]; missingData: string[]; } /** * CTA button in sales context */ export interface CTAButton { label: string; action: string; url?: string; target?: string; } /** * Sales-aware chat response (extends standard chat response) */ export interface SalesChatResponse { reply: string; sessionId: string; sources: Source[]; salesContext?: SalesContext; } /** * Visitor init response */ export interface VisitorInitResponse { visitorId: string; isReturnVisit: boolean; greeting?: string; matchedPlaybookId?: string; } /** * Lead capture response */ export interface LeadCaptureResponse { success: boolean; leadId: string; leadScore: number; leadCategory: 'hot' | 'warm' | 'cold'; message: string; } //# sourceMappingURL=types.d.ts.map