/** * Demo Experience Type Definitions * * Types for the investor demo experience orchestration. */ /** * Demo experience state machine * * Tracks the current state of the demo experience flow: * - `idle`: Demo not started yet * - `gating`: Showing gating form for lead capture * - `connecting`: Creating session and joining room * - `connected`: In demo session (greeter or presentation mode) * - `disconnected`: Demo has ended * - `error`: Error occurred during demo * * @example * ```typescript * const demo = createDemoExperience(config); * * demo.getState(); // 'idle' * * await demo.start(); * demo.getState(); // 'connected' * * await demo.end(); * demo.getState(); // 'disconnected' * ``` */ export type DemoState = 'idle' | 'gating' | 'connecting' | 'connected' | 'disconnected' | 'error'; /** * Demo type identifier */ export type DemoType = 'investor' | 'product' | 'custom'; /** * Timeline configuration options */ export type TimelineConfig = 'investor_demo' | 'investor_demo_quick'; /** * Configuration options for createDemoExperience() * * @example * ```typescript * // Minimal configuration - gating form will collect customer info * const demo = createDemoExperience({ * clientId: 'acme-corp', * }); * ``` * * @example * ```typescript * // With pre-filled customer data (skips gating form) * const demo = createDemoExperience({ * clientId: 'acme-corp', * customerName: 'Jane Smith', * customerEmail: 'jane@acme.com', * customerCompany: 'Acme Corporation', * }); * ``` * * @example * ```typescript * // Full configuration with overrides * const demo = createDemoExperience({ * clientId: 'acme-corp', * customerName: 'Jane Smith', * customerEmail: 'jane@acme.com', * customerCompany: 'Acme Corp', * deckUrl: 'https://example.com/custom-deck', * timelineConfig: 'investor_demo_quick', * demoType: 'investor', * apiUrl: 'https://custom-api.example.com', * onStart: () => console.log('Started'), * onError: (error) => console.error(error), * debug: true, * }); * ``` */ export interface DemoExperienceConfig { /** * Client ID (required) * * The unique identifier for your client (the company embedding this demo). * Used for tracking, analytics, and customization. * * @required * @example 'acme-corp' */ clientId: string; /** * Customer name (optional) * * The end customer's full name. If not provided, the gating form will * collect this information before starting the demo. * * @optional * @example 'Jane Smith' */ customerName?: string; /** * Customer email (optional) * * The end customer's email for lead capture. If not provided, the gating * form will collect this information before starting the demo. * * @optional * @example 'jane@acme.com' */ customerEmail?: string; /** * Supabase project URL * * Optional override for Supabase URL. If not provided, will be * fetched automatically from the backend API. * * @optional * @example 'https://abcdefgh.supabase.co' * @internal Not typically needed by customers */ supabaseUrl?: string; /** * Supabase anonymous key * * Optional override for Supabase anonymous key. If not provided, * will be fetched automatically from the backend API. * * @optional * @example 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' * @internal Not typically needed by customers */ supabaseKey?: string; /** * Customer company (optional) * * Optional company name for personalization. If provided, the greeter * agent may reference the company during the conversation. * * @optional * @example 'Acme Corporation' */ customerCompany?: string; /** * URL to the presentation deck * * Falls back to default investor deck if not provided. * * @optional * @default System default investor deck URL * @example 'https://example.com/decks/custom-investor-deck' */ deckUrl?: string; /** * Timeline configuration to use * * Controls the handoff timing from greeter to presentation agent: * - `'investor_demo'`: Standard 50-second greeter warmup (default) * - `'investor_demo_quick'`: Quick 20-second greeter for testing * * The timeline config determines when the SessionMetronome will * trigger the `presentation_handoff` event. * * @optional * @default 'investor_demo' * @example 'investor_demo_quick' */ timelineConfig?: TimelineConfig; /** * Type of demo experience * * Categorizes the demo for analytics and tracking purposes: * - `'investor'`: Investor pitch demo (default) * - `'product'`: Product demo * - `'custom'`: Custom demo type * * @optional * @default 'investor' */ demoType?: DemoType; /** * Backend API base URL * * The base URL for the slide-api backend. If not provided, * uses the default production API URL. * * @optional * @default 'https://slide-api-production.up.railway.app' * @example 'https://custom-api.example.com' */ apiUrl?: string; /** * Enable debug logging * * When true, enables verbose console logging for debugging * the demo experience flow. * * @optional * @default false */ debug?: boolean; /** * Called when demo starts (after gating form submitted) * * Triggered after the gating form is submitted (if enabled) and * the session creation begins. * * @optional * @example * ```typescript * onStart: () => { * console.log('Demo started'); * analytics.track('demo_started'); * } * ``` */ onStart?: () => void; /** * Called when demo ends * * Triggered when the customer disconnects or the demo is * manually ended. * * @optional * @example * ```typescript * onEnd: () => { * console.log('Demo ended'); * analytics.track('demo_ended'); * } * ``` */ onEnd?: () => void; /** * Called on demo errors * * Provides error information for debugging and user feedback. * * @optional * @param error - The error that occurred * @example * ```typescript * onError: (error) => { * console.error('Demo error:', error); * showErrorNotification(error.message); * } * ``` */ onError?: (error: Error) => void; /** * Called when demo state changes * * Useful for tracking the demo flow and updating UI accordingly. * * @optional * @param state - The new demo state * @example * ```typescript * onStateChange: (state) => { * console.log('State changed to:', state); * updateLoadingIndicator(state === 'connecting'); * } * ``` */ onStateChange?: (state: DemoState) => void; /** * Called when greeter handoff occurs * * Triggered when the SessionMetronome fires the `presentation_handoff` * event and the transition from greeter to presentation agent begins. * * @optional * @example * ```typescript * onHandoff: () => { * console.log('Handoff to presentation'); * analytics.track('demo_handoff'); * } * ``` */ onHandoff?: () => void; } /** * Demo experience instance returned by createDemoExperience() * * @example * ```typescript * const demo = createDemoExperience({ * customerName: 'Jane Smith', * customerEmail: 'jane@acme.com', * supabaseUrl: 'https://project.supabase.co', * supabaseKey: 'anon-key', * }); * * // Start the demo * await demo.start(); * * // Check current state * console.log(demo.getState()); // 'connected' * * // Later, end the demo * await demo.end(); * * // Clean up resources * demo.destroy(); * ``` */ export interface DemoExperience { /** * Unique session ID for this demo * * Generated when the demo experience is created. Use this ID * to track the session in analytics or backend systems. * * @readonly * @example 'session-1234567890-abc123' */ readonly sessionId: string; /** * Start the demo experience * * Begins the demo flow: * 1. Shows gating form (if enabled) * 2. Creates LiveKit session with greeter timeline config * 3. Joins LiveKit room * 4. Greeter agent starts conversation * 5. Waits for handoff event (T+50s or T+20s) * 6. Transitions to presentation agent with screenshare * * @throws {Error} If demo is already started or destroyed * @throws {Error} If session creation fails * @throws {Error} If room connection fails * * @example * ```typescript * try { * await demo.start(); * console.log('Demo started successfully'); * } catch (error) { * console.error('Failed to start demo:', error); * } * ``` */ start(): Promise; /** * End the demo experience * * Disconnects from the LiveKit room, stops all agents and bots, * and cleans up resources. Safe to call multiple times. * * @example * ```typescript * await demo.end(); * console.log('Demo ended'); * ``` */ end(): Promise; /** * Get current demo state * * Returns the current state of the demo experience. * Useful for UI updates and flow control. * * @returns Current demo state * * @example * ```typescript * const state = demo.getState(); * if (state === 'connected') { * console.log('Demo is running'); * } * ``` */ getState(): DemoState; /** * Destroy and cleanup all resources * * Destroys the demo experience instance and releases all resources. * After calling this, the demo instance cannot be used anymore. * * Call `end()` first to gracefully disconnect before destroying. * * @example * ```typescript * await demo.end(); * demo.destroy(); * ``` */ destroy(): void; } /** * System defaults for demo experience */ export declare const DEMO_DEFAULTS: { /** * Default timeline config (50s greeter) */ readonly timelineConfig: TimelineConfig; /** * Default demo type */ readonly demoType: DemoType; /** * Default API URL */ readonly apiUrl: "https://slide-api-production.up.railway.app"; /** * Default deck URL (to be determined) */ readonly deckUrl: string | undefined; /** * Default avatar image (to be determined) */ readonly avatarImage: string | undefined; };