/** * @unbrowser/core - Client Implementation * * The main UnbrowserClient class with all browsing, workflow, * and skill pack functionality. * * @module client * @packageDocumentation */ import type { UnbrowserConfig, BrowseOptions, BrowseResult, BatchResult, SessionData, DomainIntelligence, BrowsePreview, FuzzDiscoveryOptions, FuzzDiscoveryResult, ProgressCallback, UsageStats, HealthStatus, SkillPack, SkillExportOptions, SkillImportOptions, SkillImportResult, SkillVertical } from './types.js'; import { type SDKCapabilities, type MethodInfo } from './introspection.js'; /** * Official client for the Unbrowser cloud API. * * @description * UnbrowserClient provides intelligent web browsing for AI agents. * It learns from browsing patterns, discovers APIs automatically, * and progressively optimizes to bypass browser rendering. * * ## Key Features * * - **Tiered Rendering**: Intelligence (~50ms) -> Lightweight (~200ms) -> Playwright (~2-5s) * - **API Discovery**: Automatically discovers and caches API patterns * - **Workflow Recording**: Record and replay browsing workflows * - **Skill Packs**: Export and import portable skill collections * * ## Quick Start * * ```typescript * import { createUnbrowser } from '@unbrowser/core'; * * const client = createUnbrowser({ * apiKey: process.env.UNBROWSER_API_KEY * }); * * // Browse a URL * const result = await client.browse('https://example.com'); * console.log(result.content.markdown); * * // Discover this client's capabilities * const caps = client.describe(); * console.log(caps.description); * ``` * * ## Self-Discovery * * This SDK is designed for LLM agents. Use these methods to discover capabilities: * * - `describe()` - Get high-level SDK capabilities * - `getMethodInfo(name)` - Get detailed info about a method * - `listMethods()` - List all available methods * - `searchMethods(query)` - Search for methods by description * * @see https://docs.unbrowser.ai for full documentation */ export declare class UnbrowserClient { private readonly apiKey; private readonly baseUrl; private readonly timeout; private readonly retry; private readonly maxRetries; /** * Create a new UnbrowserClient. * * @param config - Configuration options including API key * @throws {UnbrowserError} If API key is missing or invalid * * @example * ```typescript * const client = new UnbrowserClient({ * apiKey: 'ub_live_xxxxx', * timeout: 60000 * }); * ``` */ constructor(config: UnbrowserConfig); /** * Get a high-level description of SDK capabilities. * * @description * Returns an overview of what this SDK can do, organized by category. * Use this to understand the SDK before diving into specific methods. * * This method is designed for LLM discovery - call it first to understand * what's available. * * @example * ```typescript * const caps = client.describe(); * console.log(caps.description); * * for (const category of caps.categories) { * console.log(`${category.name}:`); * for (const method of category.methods) { * console.log(` - ${method}`); * } * } * ``` */ describe(): SDKCapabilities; /** * Get detailed information about a specific method. * * @description * Returns comprehensive information about a method including: * - Description and details * - All parameters with types and examples * - Return type * - Example code * - Related methods and use cases * * @param methodName - Name of the method to get info about * @returns Method information or undefined if not found * * @example * ```typescript * const info = client.getMethodInfo('browse'); * console.log(info?.description); * console.log(info?.example); * * for (const param of info?.parameters || []) { * console.log(`${param.name}: ${param.type} - ${param.description}`); * } * ``` */ getMethodInfo(methodName: string): MethodInfo | undefined; /** * List all available methods on this client. * * @description * Returns an array of method names. Use with getMethodInfo() to * get details about each method. * * @example * ```typescript * const methods = client.listMethods(); * console.log(`Available methods: ${methods.length}`); * * for (const name of methods) { * const info = client.getMethodInfo(name); * console.log(`${name}: ${info?.description}`); * } * ``` */ listMethods(): string[]; /** * Search for methods matching a query. * * @description * Searches method names, descriptions, and use cases for matching terms. * Returns results sorted by relevance. * * @param query - Search query (e.g., "extract content", "batch") * @returns Array of matching methods with relevance scores * * @example * ```typescript * const results = client.searchMethods('extract content from web page'); * * for (const { method, relevance } of results) { * if (relevance === 'high') { * const info = client.getMethodInfo(method); * console.log(`${method}: ${info?.description}`); * } * } * ``` */ searchMethods(query: string): Array<{ method: string; relevance: 'high' | 'medium' | 'low'; }>; /** * Generate llms.txt content for this SDK. * * @description * Creates content following the llms.txt specification (llmstxt.org). * This provides a curated, LLM-readable summary of the SDK. * * @example * ```typescript * const llmsTxt = client.generateLlmsTxt(); * // Save to file or serve at /llms.txt * ``` */ generateLlmsTxt(): string; /** * Browse a URL and extract content. * * @description * The primary method for web content extraction. Uses a tiered approach: * * 1. **Intelligence tier** (~50-200ms): Uses learned patterns and cached data * 2. **Lightweight tier** (~200-500ms): Uses linkedom for simple rendering * 3. **Playwright tier** (~2-5s): Full browser for complex pages * * The SDK automatically selects the best tier based on domain knowledge. * * @param url - URL to browse (must include protocol) * @param options - Extraction options (content type, wait conditions, etc.) * @param session - Session data for authenticated browsing * @returns Extracted content with metadata * * @throws {UnbrowserError} On network, authentication, or extraction errors * * @example Basic usage * ```typescript * const result = await client.browse('https://example.com'); * console.log(result.content.markdown); * ``` * * @example With options * ```typescript * const result = await client.browse('https://example.com', { * contentType: 'markdown', * includeTables: true, * waitForSelector: '.content-loaded', * verify: { enabled: true, mode: 'thorough' } * }); * * if (result.verification?.passed) { * console.log('Content verified'); * } * ``` * * @example With session * ```typescript * const result = await client.browse('https://example.com/dashboard', {}, { * cookies: [{ name: 'session', value: 'token123' }] * }); * ``` */ browse(url: string, options?: BrowseOptions, session?: SessionData): Promise; /** * Preview how a URL will be browsed without executing. * * @description * Returns the execution plan, estimated time, and confidence level * without actually browsing. Use this to: * * - Estimate time before committing * - Check if a URL is worth browsing * - Understand the SDK's approach * * Preview completes in ~50ms vs 2-5s for actual browsing. * * @param url - URL to preview * @param options - Browse options to preview * @returns Execution plan with time estimates * * @example * ```typescript * const preview = await client.previewBrowse('https://example.com'); * * console.log(`Expected time: ${preview.estimatedTime.expected}ms`); * console.log(`Confidence: ${preview.confidence.overall}`); * console.log(`Will use ${preview.plan.tier} tier`); * * // Decide whether to proceed * if (preview.estimatedTime.expected < 5000) { * const result = await client.browse('https://example.com'); * } * ``` */ previewBrowse(url: string, options?: BrowseOptions): Promise; /** * Browse with real-time progress updates. * * @description * Same as browse() but provides progress callbacks as the operation proceeds. * Uses Server-Sent Events for real-time updates. * * @param url - URL to browse * @param onProgress - Callback for progress events * @param options - Browse options * @param session - Session data * @returns Same as browse() * * @example * ```typescript * const result = await client.browseWithProgress( * 'https://example.com', * (event) => { * console.log(`Stage: ${event.stage}`); * console.log(`Elapsed: ${event.elapsed}ms`); * if (event.tier) console.log(`Tier: ${event.tier}`); * } * ); * ``` */ browseWithProgress(url: string, onProgress: ProgressCallback, options?: BrowseOptions, session?: SessionData): Promise; /** * Fast content fetch with tiered rendering. * * @description * Optimized version of browse() for speed. * May skip some extraction steps to reduce latency. * * @param url - URL to fetch * @param options - Fetch options * @param session - Session data * @returns Extracted content * * @example * ```typescript * const result = await client.fetch('https://api.example.com/data'); * console.log(result.content.text); * ``` */ fetch(url: string, options?: BrowseOptions, session?: SessionData): Promise; /** * Browse multiple URLs in parallel. * * @description * Efficiently browse many URLs at once. Returns results for each URL * with individual success/failure status. * * More efficient than sequential browse() calls due to: * - Connection pooling * - Parallel execution * - Shared domain intelligence * * @param urls - Array of URLs to browse * @param options - Options applied to all URLs * @param session - Session data applied to all URLs * @returns Results for each URL * * @example * ```typescript * const result = await client.batch([ * 'https://example.com/page1', * 'https://example.com/page2', * 'https://example.com/page3' * ], { contentType: 'markdown' }); * * for (const item of result.results) { * if (item.success) { * console.log(`${item.url}: ${item.data?.title}`); * } else { * console.log(`${item.url} failed: ${item.error?.message}`); * } * } * ``` */ batch(urls: string[], options?: BrowseOptions, session?: SessionData): Promise; /** * Get intelligence gathered about a domain. * * @description * Returns learned patterns, success rates, and recommendations. * Use this to understand how well the SDK knows a domain * and what strategies to use. * * @param domain - Domain to get intelligence for (without protocol) * @returns Domain intelligence * * @example * ```typescript * const intel = await client.getDomainIntelligence('github.com'); * * console.log(`Known patterns: ${intel.knownPatterns}`); * console.log(`Success rate: ${(intel.successRate * 100).toFixed(0)}%`); * * if (intel.knownPatterns > 5 && intel.successRate > 0.9) { * console.log('Domain is well-known, expect fast responses'); * } * * if (intel.shouldUseSession) { * console.log('Recommendation: Use session for this domain'); * } * ``` */ getDomainIntelligence(domain: string): Promise; /** * Discover API endpoints via intelligent fuzzing. * * @description * Probes common API paths on a domain to discover endpoints. * Discovered APIs are cached and used directly for future requests, * bypassing browser rendering for 10x speedup. * * @param domain - Domain to discover APIs on * @param options - Discovery options (paths, methods, timeouts) * @returns Discovery results with found endpoints * * @example Conservative discovery (safe) * ```typescript * const result = await client.discoverApis('api.github.com', { * methods: ['GET'], * learnPatterns: true * }); * * console.log(`Discovered ${result.discovered.length} endpoints`); * ``` * * @example Aggressive discovery * ```typescript * const result = await client.discoverApis('api.example.com', { * methods: ['GET', 'POST', 'PUT', 'DELETE'], * paths: ['/api', '/api/v1', '/graphql'], * probeTimeout: 5000, * maxDuration: 60000 * }); * ``` */ discoverApis(domain: string, options?: FuzzDiscoveryOptions): Promise; /** * Start recording a workflow. * * @description * Begins a recording session that captures all subsequent browse operations. * Stop recording to save the workflow as a reusable skill. * * @param request - Workflow metadata (name, description, domain) * @returns Recording session information * * @example * ```typescript * // Start recording * const session = await client.startRecording({ * name: 'Extract product pricing', * description: 'Navigate to product page and extract price', * domain: 'shop.example.com' * }); * * // Browse operations are now recorded * await client.browse('https://shop.example.com/product/123'); * * // Stop and save * const workflow = await client.stopRecording(session.recordingId); * console.log(`Saved: ${workflow.workflowId}`); * ``` */ startRecording(request: { name: string; description: string; domain: string; tags?: string[]; }): Promise<{ recordingId: string; status: string; startedAt: string; }>; /** * Stop a recording session and save the workflow. * * @param recordingId - Recording session ID from startRecording() * @param save - Whether to save the workflow (default: true) * @returns Saved workflow information or null if not saved */ stopRecording(recordingId: string, save?: boolean): Promise<{ workflowId: string; skillId: string; name: string; steps: number; estimatedDuration: number; } | null>; /** * Annotate a step in an active recording. * * @description * Mark steps as critical/important/optional and add descriptions. * Annotations help during replay to understand step importance. * * @param recordingId - Recording session ID * @param annotation - Annotation details * @returns Annotation confirmation */ annotateRecording(recordingId: string, annotation: { stepNumber: number; annotation: string; importance?: 'critical' | 'important' | 'optional'; }): Promise<{ recordingId: string; stepNumber: number; annotated: boolean; }>; /** * Replay a saved workflow. * * @description * Executes a previously recorded workflow. * Variables in the workflow can be substituted with provided values. * * @param workflowId - Workflow ID from stopRecording() * @param variables - Variable values to substitute * @returns Replay results for each step * * @example * ```typescript * // Replay with different product ID * const results = await client.replayWorkflow('wf_xyz789', { * productId: '456' * }); * * if (results.overallSuccess) { * console.log(`Completed in ${results.totalDuration}ms`); * } else { * // Check which steps failed * for (const step of results.results) { * if (!step.success) { * console.log(`Step ${step.stepNumber} failed: ${step.error}`); * } * } * } * ``` */ replayWorkflow(workflowId: string, variables?: Record): Promise<{ workflowId: string; overallSuccess: boolean; totalDuration: number; results: Array<{ stepNumber: number; success: boolean; duration: number; tier?: 'intelligence' | 'lightweight' | 'playwright'; error?: string; }>; }>; /** * List saved workflows. * * @param options - Filter by domain or tags * @returns List of workflows with metadata */ listWorkflows(options?: { domain?: string; tags?: string[]; }): Promise<{ workflows: Array<{ id: string; name: string; description: string; domain: string; tags: string[]; steps: number; version: number; usageCount: number; successRate: number; createdAt: string; updatedAt: string; }>; total: number; }>; /** * Get workflow details including all steps. * * @param workflowId - Workflow ID * @returns Full workflow details */ getWorkflow(workflowId: string): Promise<{ id: string; name: string; description: string; domain: string; tags: string[]; version: number; usageCount: number; successRate: number; skillId?: string; steps: Array<{ stepNumber: number; action: string; url?: string; description: string; userAnnotation?: string; importance: 'critical' | 'important' | 'optional'; tier?: 'intelligence' | 'lightweight' | 'playwright'; duration?: number; success: boolean; }>; createdAt: string; updatedAt: string; }>; /** * Delete a saved workflow. * * @param workflowId - Workflow ID to delete * @returns Deletion confirmation */ deleteWorkflow(workflowId: string): Promise<{ workflowId: string; deleted: boolean; }>; /** * Export skills as a portable skill pack. * * @description * Creates a JSON skill pack that can be shared or imported. * Filter by domain, vertical, or quality metrics. * * @param options - Export filter options * @returns Exported skill pack with metadata * * @example * ```typescript * const { pack } = await client.exportSkillPack({ * domainPatterns: ['github.com'], * minSuccessRate: 0.8, * packName: 'GitHub Skills' * }); * * // Save to file * fs.writeFileSync('github-skills.json', JSON.stringify(pack, null, 2)); * ``` */ exportSkillPack(options?: SkillExportOptions): Promise<{ success: boolean; pack: SkillPack; metadata: { skillCount: number; antiPatternCount: number; workflowCount: number; version: string; createdAt: number; }; }>; /** * Import a skill pack. * * @description * Installs skills from a skill pack. * Configure conflict resolution and filtering. * * @param pack - The skill pack to import * @param options - Import options including conflict resolution * @returns Import results with counts */ importSkillPack(pack: SkillPack, options?: SkillImportOptions): Promise<{ success: boolean; result: SkillImportResult; }>; /** * Browse the official skill pack library. * * @param options - Filter by vertical or search * @returns List of available skill packs */ listSkillPackLibrary(options?: { vertical?: SkillVertical; search?: string; }): Promise<{ success: boolean; packs: Array<{ id: string; name: string; description: string; version: string; verticals: SkillVertical[]; domains: string[]; skillCount: number; downloadCount: number; verified: boolean; npmUrl: string; }>; total: number; }>; /** * Install a skill pack from the official library. * * @param packId - Skill pack ID or npm package name * @param options - Import options * @returns Import results */ installSkillPack(packId: string, options?: SkillImportOptions): Promise<{ success: boolean; result: SkillImportResult; }>; /** * Get statistics about loaded skills. * * @returns Skill counts by vertical and tier, plus loading statistics */ getSkillPackStats(): Promise<{ success: boolean; totalSkills: number; totalWorkflows: number; totalAntiPatterns: number; byVertical: Record; byTier: { essential: number; 'domain-specific': number; advanced: number; }; loadingStats: { totalLoaded: number; totalUnloaded: number; loadedDomains: string[]; }; }>; /** * Get usage statistics for the current billing period. * * @returns Usage statistics with period, counts, and limits * * @example * ```typescript * const usage = await client.getUsage(); * * console.log(`Period: ${usage.period.start} to ${usage.period.end}`); * console.log(`Total requests: ${usage.requests.total}`); * console.log(`Remaining: ${usage.limits.remaining} of ${usage.limits.daily}`); * * // Warn on low quota * if (usage.limits.remaining < 100) { * console.warn('Low quota warning'); * } * ``` */ getUsage(): Promise; /** * Check API health status. * * @description * Returns API status, version, and uptime. * Does not require authentication. * * @returns Health status * * @example * ```typescript * const status = await client.health(); * console.log(`Status: ${status.status}`); * console.log(`Version: ${status.version}`); * ``` */ health(): Promise; /** * Make an authenticated request to the API with retry logic. */ private request; } /** * Create an Unbrowser client for cloud API access. * * @description * Factory function for creating an UnbrowserClient instance. * This is the recommended way to create a client. * * @param config - Configuration including API key * @returns Configured UnbrowserClient instance * * @example * ```typescript * import { createUnbrowser } from '@unbrowser/core'; * * // Create client * const client = createUnbrowser({ * apiKey: process.env.UNBROWSER_API_KEY * }); * * // Use client * const result = await client.browse('https://example.com'); * console.log(result.content.markdown); * * // Discover capabilities * const caps = client.describe(); * console.log(caps.categories.map(c => c.name)); * ``` */ export declare function createUnbrowser(config: UnbrowserConfig): UnbrowserClient; //# sourceMappingURL=client.d.ts.map