/** * Research Engine * * General-purpose research capability that combines web search with * intelligent browsing to answer research questions with citations. * * Architecture: * 1. Takes natural language research scope * 2. Uses web search APIs to find authoritative sources * 3. Browses and extracts structured data from sources * 4. Cross-verifies across multiple sources * 5. Returns structured results with confidence and citations * * This is the core abstraction that makes Unbrowser a "research engine" * rather than just a browser automation tool. * * @example * ```typescript * const result = await researchEngine.research({ * scope: "current IPREM rates in Spain for 2025", * outputSchema: { * type: "object", * properties: { * monthly: { type: "number", description: "Monthly IPREM in EUR" }, * annual14: { type: "number", description: "Annual IPREM (14 payments)" } * } * }, * strategy: "authoritative" * }); * ``` */ /** * Research request - the input to the research engine */ export interface ResearchRequest { /** * Natural language description of what to research. * Examples: * - "current IPREM rates in Spain for 2025" * - "Portugal D7 visa income requirements" * - "US 401k contribution limits for 2025" */ scope: string; /** * Optional JSON schema for the output. * If provided, the engine will try to extract data matching this schema. * If not provided, returns unstructured findings. */ outputSchema?: JsonSchema; /** * Research strategy * - "authoritative": Prioritize official/government sources * - "comprehensive": Cast wide net, gather multiple perspectives * - "quick": Fast results from top sources only */ strategy?: 'authoritative' | 'comprehensive' | 'quick'; /** * Maximum number of sources to consult * Default: 5 for authoritative, 10 for comprehensive, 3 for quick */ maxSources?: number; /** * Language hint for search and extraction */ language?: string; /** * Domain hints - prefer these domains if relevant */ preferredDomains?: string[]; /** * Previous research result for change detection */ previousResult?: ResearchResult; /** * Use search snippets only - skip browsing for maximum speed. * * When true, the engine uses search result descriptions (snippets) directly * instead of browsing each URL. This matches Claude WebSearch behavior and * achieves ~300-500ms response times vs 2-60+ seconds with browsing. * * Trade-offs: * - PRO: 10-100x faster (no browser rendering) * - PRO: Still includes source classification, authority scoring, contradiction detection * - CON: Less content (100-300 char snippets vs full pages) * - CON: Cannot extract structured data (no outputSchema support) * * Best for: Quick factual lookups, policy change detection, source discovery * Not for: Deep extraction with outputSchema, content that requires full page context */ snippetsOnly?: boolean; } /** * JSON Schema (simplified) */ export interface JsonSchema { type: 'object' | 'array' | 'string' | 'number' | 'boolean'; properties?: Record; items?: JsonSchemaProperty; required?: string[]; description?: string; } export interface JsonSchemaProperty { type: 'string' | 'number' | 'boolean' | 'array' | 'object'; description?: string; enum?: (string | number)[]; items?: JsonSchemaProperty; properties?: Record; } /** * A source consulted during research */ export interface ResearchSource { /** Source URL */ url: string; /** Page title */ title: string; /** Domain */ domain: string; /** Source type classification */ sourceType: 'government' | 'official' | 'news' | 'reference' | 'blog' | 'unknown'; /** Authority score (0-1) */ authorityScore: number; /** When the source was fetched */ fetchedAt: string; /** Relevant excerpt from source */ excerpt?: string; /** Data extracted from this source */ extractedData?: Record; /** Whether extraction succeeded */ extractionSuccess: boolean; /** Error if extraction failed */ extractionError?: string; } /** * Cross-verification result */ export interface VerificationResult { /** Whether sources agree */ sourcesAgree: boolean; /** Number of sources that agree */ agreementCount: number; /** Total sources consulted */ totalSources: number; /** Disagreements found */ disagreements?: Array<{ field: string; values: Array<{ source: string; value: unknown; }>; }>; /** Confidence from verification */ verificationConfidence: number; } /** * Change detection result */ export interface ChangeDetection { /** Whether data changed from previous */ hasChanged: boolean; /** Fields that changed */ changedFields: Array<{ field: string; previousValue: unknown; currentValue: unknown; changeType: 'added' | 'removed' | 'modified'; }>; /** Change severity */ severity: 'none' | 'minor' | 'major' | 'breaking'; /** Human-readable summary */ summary: string; } /** * Research progress event for SSE streaming */ export interface ResearchProgressEvent { /** Stage of research */ stage: 'started' | 'searching' | 'browsing' | 'extracting' | 'verifying' | 'completed' | 'error'; /** Elapsed time in ms */ elapsed: number; /** Current source index (1-based) */ currentSource?: number; /** Total sources to process */ totalSources?: number; /** URL currently being processed */ currentUrl?: string; /** Message for display */ message?: string; /** Error message if stage is 'error' */ error?: string; } /** * Callback for research progress events */ export type ResearchProgressCallback = (event: ResearchProgressEvent) => void | Promise; /** * QA-FEAT-001: Human-readable confidence explanation */ export interface ConfidenceExplanation { /** Brief summary (e.g., "2 sources agree, 1 disagrees on monthlyAmount") */ summary: string; /** Detailed breakdown of factors */ factors: Array<{ factor: string; score: number; description: string; }>; /** Fields with disagreements */ disagreements?: Array<{ field: string; description: string; }>; /** Suggestions for improving confidence */ suggestions?: string[]; } /** * Complete research result */ export interface ResearchResult { /** Whether research succeeded */ success: boolean; /** Error message if failed */ error?: string; /** The research scope that was requested */ scope: string; /** * Extracted data matching the output schema. * If no schema provided, contains unstructured findings. */ data: Record | null; /** Overall confidence score (0-1) */ confidence: number; /** * QA-FEAT-001: Human-readable explanation of confidence score * Explains why the confidence is what it is, including source agreement/disagreement */ confidenceExplanation: ConfidenceExplanation; /** Confidence breakdown */ confidenceFactors: { sourceQuality: number; extractionSuccess: number; crossVerification: number; schemaMatch: number; }; /** Sources consulted */ sources: ResearchSource[]; /** Cross-verification results */ verification: VerificationResult; /** Change detection (if previousResult provided) */ changes?: ChangeDetection; /** Research metadata */ metadata: { /** Total time taken */ durationMs: number; /** Search queries used */ searchQueries: string[]; /** Strategy used */ strategy: string; /** When research was performed */ performedAt: string; }; } /** * Search provider interface */ export interface SearchProvider { name: string; search(query: string, options?: SearchOptions): Promise; } export interface SearchOptions { /** Maximum results */ maxResults?: number; /** Country/region hint */ country?: string; /** Language hint */ language?: string; /** Freshness filter */ freshness?: 'day' | 'week' | 'month' | 'year'; } export interface SearchResult { title: string; url: string; description: string; /** Published date if available */ publishedDate?: string; } /** * Brave Search provider */ export declare class BraveSearchProvider implements SearchProvider { name: string; private apiKey; private baseUrl; private maxRetries; private retryDelayMs; constructor(apiKey: string); search(query: string, options?: SearchOptions): Promise; } /** * Research Engine - combines search + browsing for intelligent research */ export declare class ResearchEngine { private browser; private searchProvider; /** * Initialize the research engine */ initialize(config?: { searchProvider?: SearchProvider; braveApiKey?: string; }): Promise; /** * Perform research based on natural language scope */ research(request: ResearchRequest): Promise; /** * Perform research with progress callbacks for SSE streaming */ researchWithProgress(request: ResearchRequest, onProgress: ResearchProgressCallback): Promise; /** * Cleanup resources */ close(): Promise; } /** * Get the default research engine instance */ export declare function getResearchEngine(): Promise; /** * Perform research using the default engine */ export declare function research(request: ResearchRequest): Promise; //# sourceMappingURL=research-engine.d.ts.map