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; /** Optional response post-processing applied at `done`/REST completion. */ responseNormalization?: ResponseNormalizationConfig; /** 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: 7 — ADR-001). The client slices the * array returned from both REST and WebSocket transports to this size * before handing it to consumers. */ maxSources?: number; } /** * Configuration for response normalization (ADR-001). * * The backend `extract` step usually wraps monospace runs in triple-backtick * fences, but for tenants on older Lambdas, the LLM may emit a single- * backtick run that contains a newline (e.g., ` `tar -xzf file.tar.gz` ` * collapsed to one inline run with literal \n inside). When `enabled` is * true, the client converts those into proper triple-backtick fences at * `done`-event assembly time so the rendered widget shows a real `
`
 * block instead of a single-line ``.
 *
 * Off by default for backwards compatibility.
 */
export interface ResponseNormalizationConfig {
    /** Enable normalization passes on accumulated reply text (default: false) */
    enabled?: boolean;
    /** Promote single-backtick runs that contain a newline to triple-backtick fenced blocks (default: true when enabled) */
    normalizeFencedBlocks?: boolean;
}
/**
 * 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;
    };
    /** Whether to show source citations (from backend admin settings, ADR-095) */
    showSources?: boolean;
    /** Whether to allow source file downloads (from backend admin settings, ADR-095) */
    allowDownloads?: boolean;
}
/**
 * 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