/** * Smart Browser - Unified intelligent browsing with automatic learning * * This is the main orchestrator that ties together all learning features * into a cohesive, intelligent browsing experience for AI agents. * * Key capabilities: * - Automatic content extraction with learned selectors * - Fallback selector chains when primary fails * - Response validation with learned rules * - Automatic learning from successes and failures * - Cross-domain pattern transfer * - Pagination detection and handling * - Change frequency tracking * - Intelligent retry with failure context */ import type { Page } from 'playwright'; import type { BrowseResult, BrowseOptions, SelectorPattern, PaginationPattern, BrowsingAction, PageContext, SkillMatch, SkillExecutionTrace, BrowsingSkill, RenderTier, BrowseFieldConfidence, OnProgressCallback } from '../types/index.js'; import { type DecisionTrace } from '../types/decision-trace.js'; import { BrowserManager } from './browser-manager.js'; import { type SkillProvenance } from './skill-provenance.js'; import { ContentExtractor, type TableAsJSON } from '../utils/content-extractor.js'; import { ApiAnalyzer } from './api-analyzer.js'; import { SessionManager } from './session-manager.js'; import { LearningEngine } from './learning-engine.js'; import { ProceduralMemory } from './procedural-memory.js'; import type { WebSocketReplayOptions, WebSocketReplayResult } from '../types/websocket-patterns.js'; import { TieredFetcher, type FreshnessRequirement } from './tiered-fetcher.js'; import { type SemanticInfrastructure } from './semantic-init.js'; import { DebugTraceRecorder } from '../utils/debug-trace-recorder.js'; import type { HarExportOptions, HarExportResult } from '../types/har.js'; import { FeedbackService } from './feedback-service.js'; import { WebhookService } from './webhook-service.js'; import { type ChallengeCallback, type CaptchaHandlingResult } from './captcha-handler.js'; export interface SmartBrowseOptions extends BrowseOptions { extractContent?: boolean; contentType?: SelectorPattern['contentType']; /** * Extract structured data (JSON-LD, microdata, OpenGraph, * Twitter Card, Dublin Core, RDFa) from the rendered HTML and * surface it on `metadata.structuredData` and `metadata.extracted`. * * Defaults to true. Set to false to skip extraction (rare — * extraction is cheap because the HTML is already in memory by * the time we'd run the extractor). */ extract?: boolean; retryConfig?: import('../types/index.js').RetryConfig; validateContent?: boolean; followPagination?: boolean; maxPages?: number; enableLearning?: boolean; checkForChanges?: boolean; useSkills?: boolean; recordTrajectory?: boolean; useTieredFetching?: boolean; forceTier?: RenderTier; minContentLength?: number; includeDecisionTrace?: boolean; maxLatencyMs?: number; maxCostTier?: RenderTier; freshnessRequirement?: FreshnessRequirement; debug?: { visible?: boolean; slowMotion?: number; screenshots?: boolean; consoleLogs?: boolean; }; includeAccessibilityTree?: boolean; includeAccessibilityBounds?: boolean; recordDebugTrace?: boolean; verify?: import('../types/verification.js').VerifyOptions; onProgress?: OnProgressCallback; skillPromptId?: string; skillPromptStep?: number; onChallengeDetected?: ChallengeCallback; autoSolveCaptcha?: boolean; captchaSolveTimeout?: number; skipCaptchaHandling?: boolean; } /** * Domain capabilities summary (TC-002) * Extracted for use in smart_browse response and standalone exports */ export interface DomainCapabilitiesSummary { canBypassBrowser: boolean; hasLearnedPatterns: boolean; hasActiveSession: boolean; hasSkills: boolean; hasPagination: boolean; hasContentSelectors: boolean; } /** * Domain knowledge summary (TC-002) * Extracted for use in smart_browse response and standalone exports */ export interface DomainKnowledgeSummary { patternCount: number; successRate: number; recommendedWaitStrategy: string; recommendations: string[]; } export interface SmartBrowseResult extends BrowseResult { fieldConfidence?: BrowseFieldConfidence; decisionTrace?: DecisionTrace; verification?: import('../types/verification.js').VerificationResult; learning: { selectorsUsed: string[]; selectorsSucceeded: string[]; selectorsFailed: string[]; validationResult?: { valid: boolean; reasons: string[]; }; paginationDetected?: PaginationPattern; contentChanged?: boolean; recommendedRefreshHours?: number; domainGroup?: string; confidenceLevel: 'high' | 'medium' | 'low' | 'unknown'; skillsMatched?: SkillMatch[]; skillApplied?: string; /** * Provenance of the applied skill — when it was created, when it * was last successfully invoked, success/failure counts. Lets * callers apply freshness and quality policies without reaching * into ProceduralMemory themselves. Only populated when a skill * was actually applied to this browse. * * See `SkillProvenance` for full field semantics, especially the * distinction between `lastUsedAt` (any invocation) and * `lastSuccessAt` (successful only). */ skillProvenance?: SkillProvenance; skillExecutionTrace?: SkillExecutionTrace; trajectoryRecorded?: boolean; anomalyDetected?: boolean; anomalyType?: 'challenge_page' | 'error_page' | 'empty_content' | 'redirect_notice' | 'captcha' | 'rate_limited'; anomalyAction?: 'wait' | 'retry' | 'use_session' | 'change_agent' | 'skip'; renderTier?: RenderTier; tierFellBack?: boolean; tiersAttempted?: RenderTier[]; tierReason?: string; tierTiming?: Record; budgetInfo?: { latencyExceeded: boolean; tiersSkipped: RenderTier[]; maxCostTierEnforced?: RenderTier; usedCache: boolean; freshnessApplied?: FreshnessRequirement; }; domainCapabilities?: DomainCapabilitiesSummary; domainKnowledge?: DomainKnowledgeSummary; captchaHandling?: CaptchaHandlingResult; }; additionalPages?: Array<{ url: string; content: { html: string; markdown: string; text: string; }; }>; graphql?: { /** Whether a GraphQL endpoint was discovered */ found: boolean; /** The GraphQL endpoint URL */ endpoint?: string; /** List of query names discovered */ queries?: string[]; /** List of mutation names discovered */ mutations?: string[]; /** Number of types in the schema */ typeCount?: number; /** Error message if introspection failed */ error?: string; }; } /** * Options for screenshot capture */ export interface ScreenshotOptions { fullPage?: boolean; element?: string; waitForSelector?: string; sessionProfile?: string; width?: number; height?: number; } /** * Result of a screenshot capture operation */ export interface ScreenshotResult { success: boolean; image?: string; mimeType: 'image/png'; url: string; finalUrl: string; title: string; viewport: { width: number; height: number; }; timestamp: string; durationMs: number; error?: string; } export declare class SmartBrowser { private browserManager; private contentExtractor; private apiAnalyzer; private sessionManager; private learningEngine; private proceduralMemory; private tieredFetcher; private accessibilityExtractor; private verificationEngine; private sessionSharingService; private currentTrajectory; private semanticInfrastructure; private debugRecorder; private feedbackService; private webhookService; private replayWorkflowDepth; private static readonly MAX_WORKFLOW_DEPTH; constructor(browserManager: BrowserManager, contentExtractor: ContentExtractor, apiAnalyzer: ApiAnalyzer, sessionManager: SessionManager, learningEngine?: LearningEngine); initialize(): Promise; /** * Get the tiered fetcher for direct access */ getTieredFetcher(): TieredFetcher; /** * Get the session sharing service for SSO detection and cross-domain session sharing (GAP-009) */ getSessionSharingService(): import('./session-sharing.js').SessionSharingService | null; /** * Detect SSO flow from a URL and learn domain relationships (GAP-009) * Call this when navigating to capture OAuth/SAML/OIDC flows */ detectSSOFlow(url: string, initiatingDomain?: string): import('./sso-flow-detector.js').SSOFlowInfo | null; /** * Find and share a session from a related domain that uses the same identity provider (GAP-009) * Returns true if a session was shared successfully */ shareSessionFromRelatedDomain(targetDomain: string, options?: { sessionProfile?: string; minConfidence?: number; }): Promise<{ success: boolean; sourceDomain?: string; providerId?: string; }>; /** * Get domains that share the same identity provider with the given domain (GAP-009) */ getRelatedDomains(domain: string, minConfidence?: number): string[]; /** * Get domain groups organized by identity provider (GAP-009) */ getDomainGroups(minConfidence?: number): import('./domain-correlator.js').DomainGroup[]; /** * Helper to emit progress events if callback is provided */ private emitProgress; /** * Intelligent browse with automatic learning and optimization */ browse(url: string, options?: SmartBrowseOptions): Promise; /** * Internal browse implementation (separated for timeout wrapper) */ private _browseInternal; /** * Build decision trace if requested (CX-003) * Extracts selector and title attempts from HTML and combines with tier attempts */ private buildDecisionTraceIfRequested; /** * Browse using tiered fetching (static -> lightweight -> playwright) * Returns null if it needs to fall back to full Playwright path */ private browseWithTieredFetching; /** * Wait for selector with learned fallbacks (supports semantic selectors) */ private waitForSelectorWithFallback; /** * Dismiss cookie banner with learning */ private dismissCookieBannerWithLearning; /** * Extract content using learned selectors with fallbacks */ private extractContentWithLearning; /** * Detect pagination pattern */ private detectPagination; /** * Follow pagination to get additional pages */ private followPagination; /** * Scroll page to load lazy content */ private scrollToLoadContent; /** * Detect and wait through bot challenge pages (Cloudflare, Voight-Kampff, etc.) * Enhanced with GAP-007: CAPTCHA detection and user callback support */ private waitForBotChallenge; /** * Detect page language */ private detectLanguage; /** * Utility delay function */ private delay; /** * Learn semantic selector from a successful action (Phase 2: Semantic Selectors) */ private learnSemanticSelector; /** * Get learning engine for direct access */ getLearningEngine(): LearningEngine; /** * Batch browse multiple URLs with controlled concurrency * * This method allows browsing multiple URLs in a single call, with: * - Configurable concurrency limits * - Per-URL and total timeout controls * - Individual error handling (one failure doesn't stop others) * - Shared session and pattern usage across batch * - Progress tracking with per-URL status * * @param urls Array of URLs to browse * @param browseOptions Options applied to each browse operation * @param batchOptions Options for the batch operation itself * @returns Array of results maintaining the original URL order */ batchBrowse(urls: string[], browseOptions?: SmartBrowseOptions, batchOptions?: import('../types/index.js').BatchBrowseOptions): Promise[]>; /** * Replay WebSocket connection using learned pattern (FEAT-003) * * Connects directly to WebSocket without browser rendering for 10-20x speedup. * * @param options - WebSocket replay options including pattern, auth, and duration * @returns WebSocket replay result with captured messages * * @example * ```typescript * // Get learned patterns for domain * const patterns = learningEngine.getWebSocketPatterns('chat.example.com'); * * // Replay the pattern * const result = await browser.replayWebSocket({ * pattern: patterns[0], * auth: { cookies: savedCookies }, * duration: 5000, * captureMessages: true, * }); * * console.log(`Connected: ${result.connected}`); * console.log(`Messages: ${result.messages.length}`); * ``` */ replayWebSocket(options: WebSocketReplayOptions): Promise; /** * Get intelligence summary for a domain */ getDomainIntelligence(domain: string): Promise<{ knownPatterns: number; selectorChains: number; validators: number; paginationPatterns: number; recentFailures: number; successRate: number; domainGroup: string | null; recommendedWaitStrategy: string; shouldUseSession: boolean; }>; /** * Get comprehensive capability summary for a domain (CX-011) * * This provides an LLM-friendly summary of what the system can do * for a given domain, helping the LLM make informed decisions. */ getDomainCapabilities(domain: string): Promise<{ domain: string; capabilities: { canBypassBrowser: boolean; hasLearnedPatterns: boolean; hasActiveSession: boolean; hasSkills: boolean; hasPagination: boolean; hasContentSelectors: boolean; }; confidence: { level: 'high' | 'medium' | 'low' | 'unknown'; score: number; basis: string; }; performance: { preferredTier: string; avgResponseTimeMs: number | null; successRate: number; }; recommendations: string[]; details: { apiPatternCount: number; skillCount: number; selectorCount: number; validatorCount: number; paginationPatternCount: number; recentFailureCount: number; domainGroup: string | null; }; }>; /** * Get procedural memory for direct access */ getProceduralMemory(): ProceduralMemory; /** * Get feedback service for AI feedback handling */ getFeedbackService(): FeedbackService; /** * Get webhook service for external integrations */ getWebhookService(): WebhookService; /** * Detect page context for better skill matching */ detectPageContext(page: Page, url: string): Promise; /** * Start recording a new browsing trajectory */ private startTrajectory; /** * Record an action in the current trajectory */ recordAction(action: BrowsingAction): void; /** * Complete and submit the current trajectory for skill learning */ private completeTrajectory; /** * Get procedural memory statistics */ getProceduralMemoryStats(): { totalSkills: number; totalTrajectories: number; skillsByDomain: Record; avgSuccessRate: number; mostUsedSkills: Array<{ name: string; uses: number; }>; }; /** * Find applicable skills for a given URL */ findApplicableSkills(url: string, topK?: number): SkillMatch[]; /** * Execute a single action on the page * Returns the result of the action execution */ private executeAction; /** * Execute a skill's action sequence on the page (TC-003) * Auto-applies matched skills to automate browsing workflows */ executeSkillActions(page: Page, skill: BrowsingSkill, match: SkillMatch): Promise; /** * Execute a skill with fallback chain support (TC-003) * Tries the primary skill first, then falls back to alternative skills if available */ executeSkillWithFallbacks(page: Page, primaryMatch: SkillMatch, allMatches: SkillMatch[]): Promise; /** * Compute field-level confidence for browse results * Uses extraction sources and validation results to provide per-field confidence */ computeFieldConfidence(html: string, url: string, tables: TableAsJSON[], discoveredApis: Array<{ endpoint: string; method: string; confidence: 'high' | 'medium' | 'low'; canBypass: boolean; }>, learning: SmartBrowseResult['learning']): BrowseFieldConfidence; /** * Check if semantic pattern matching is enabled * * Returns true if semantic infrastructure was successfully initialized. * When enabled, the LearningEngine will use semantic similarity search * as a fallback when exact pattern matching fails. */ isSemanticMatchingEnabled(): boolean; /** * Get the semantic infrastructure (if initialized) * * Returns the semantic infrastructure components, or null if not initialized. * Use this to access the EmbeddedStore for pattern storage or VectorStore * for direct embedding operations. */ getSemanticInfrastructure(): SemanticInfrastructure | null; /** * Get the debug trace recorder for direct access */ getDebugRecorder(): DebugTraceRecorder; /** * Record a debug trace for a browse result */ private recordDebugTraceForResult; /** * Create an error response for screenshot capture */ private createScreenshotErrorResponse; /** * Capture a screenshot of a URL * * This method navigates to the URL using Playwright (required for screenshots) * and captures a screenshot. Screenshots are not available when using * intelligence or lightweight rendering tiers. * * @param url - The URL to screenshot * @param options - Screenshot options * @returns Screenshot result with base64 image data and metadata */ captureScreenshot(url: string, options?: ScreenshotOptions): Promise; /** * Create an error response for HAR export */ private createHarErrorResponse; /** * Export HAR (HTTP Archive) for a URL * * This method navigates to the URL using Playwright (required for network capture) * and exports the network traffic in HAR 1.2 format. * * @param url - The URL to browse and capture network traffic * @param options - HAR export options * @returns HAR export result with network data */ exportHar(url: string, options?: HarExportOptions & { sessionProfile?: string; waitForSelector?: string; }): Promise; /** * Preview what will happen when browsing a URL without executing * * This provides a plan showing: * - Which tier will be used (intelligence/lightweight/playwright) * - Step-by-step execution plan * - Time estimates * - Confidence levels * - Fallback strategies * * Competitive advantage: <50ms preview vs 2-5s browser automation */ previewBrowse(url: string, options?: SmartBrowseOptions): Promise; /** * Analyze what would happen for preview (no execution) */ private analyzePreview; /** * Build execution plan from analysis */ private buildExecutionPlan; /** * Estimate execution time from plan */ private estimateExecutionTime; /** * Assess confidence from analysis */ private assessConfidence; /** * Generate alternative execution plans */ private generateAlternativePlans; /** * Map numeric confidence score to level */ private mapConfidenceScore; /** * Convert confidence level to numeric score */ private confidenceToNumber; /** * Replay a saved workflow with optional variable substitution */ replayWorkflow(workflow: import('../types/workflow.js').Workflow, variables?: import('../types/workflow.js').WorkflowVariables): Promise; /** * Internal method to execute workflow replay (separated for recursion depth tracking) */ private executeWorkflowReplay; /** * Enable debug trace recording globally */ enableDebugRecording(): void; /** * Disable debug trace recording globally */ disableDebugRecording(): void; /** * Check if debug trace recording is enabled */ isDebugRecordingEnabled(): boolean; } //# sourceMappingURL=smart-browser.d.ts.map