UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

218 lines (217 loc) • 8.56 kB
/** * File Type Detection Utility * Centralized file detection for all multimodal file types * Uses multi-strategy approach for reliable type identification */ import type { FileDetectorOptions, FileInput, FileProcessingResult } from "../types/index.js"; /** * Centralized file type detection and processing * * @example * ```typescript * // Auto-detect and process any file * const result = await FileDetector.detectAndProcess("data.csv"); * logger.info(result.type); // 'csv' * ``` */ export declare class FileDetector { static readonly DEFAULT_NETWORK_TIMEOUT = 30000; static readonly DEFAULT_HEAD_TIMEOUT = 5000; /** * Ceiling on an in-process document parse (unzip + XML walk). Generous * relative to the work, because the cost of firing early on a large but * legitimate file is a lost extraction, while the cost of never firing is a * held request. */ static readonly DEFAULT_DOCUMENT_TIMEOUT = 30000; /** * Auto-detect file type and process in one call * * Runs detection strategies in priority order: * 1. MagicBytesStrategy (95% confidence) - Binary file headers * 2. MimeTypeStrategy (85% confidence) - HTTP Content-Type for URLs * 3. ExtensionStrategy (70% confidence) - File extension * 4. ContentHeuristicStrategy (75% confidence) - Content analysis * * @param input - File path, URL, Buffer, or data URI * @param options - Detection and processing options * @returns Processed file result with type and content */ static detectAndProcess(input: FileInput, options?: FileDetectorOptions): Promise<FileProcessingResult>; /** * Set span attributes and log after file processing completes. */ private static setFileResultSpanAttributes; /** * Derive a human-readable filename from FileInput for tracing. */ private static deriveInputFilename; /** * Derive byte size from FileInput for tracing. */ private static deriveInputSize; /** * Classify a FileInput into the FileSource enum used by downstream * loaders. Keeps the mimetype-hint short-circuit in detect() able to * produce a valid FileDetectionResult without re-implementing the * source-inference rules scattered across loadContent(). */ private static deriveInputSource; /** * Try fallback parsing for a specific file type * Used when file detection returns "unknown" but we want to try parsing anyway */ private static tryFallbackParsing; /** * Check if content is valid text (UTF-8, mostly printable) */ private static isValidText; /** * Guess the MIME type for text content based on content patterns */ private static guessTextMimeType; /** * Strict YAML detection for guessTextMimeType * Similar to ContentHeuristicStrategy but requires at least 2 indicators * to avoid false positives from simple key: value patterns */ private static looksLikeYAMLStrict; /** * Strict XML detection for guessTextMimeType * Ensures content has proper XML declaration or valid tag structure with closing tags * Prevents false positives from arbitrary content starting with < */ private static looksLikeXMLStrict; /** * Detect file type using multi-strategy approach * Stops at first strategy with confidence >= threshold (default: 80%) */ private static detect; /** * Fill in `extension` from the input's name when detection did not set it. * * Content-based strategies identify a type from magic bytes and legitimately * have no extension to report, so they return null. That is fine for the type * itself but not for routing: several processors are chosen by extension * *after* detection has settled the type, because one routing type covers * several formats — `docx` covers .docx, .odt and .rtf. * * With a null extension those branches were unreachable. An .rtf scored high * on its `{\\rtf1` signature, arrived as type "docx" with no extension, and * fell through to the Word processor, which cannot read RTF — so a file whose * dedicated processor extracts it perfectly reported "Could not extract * content". The extension was known the whole time; it was simply dropped on * the way through. * * Only fills a gap — a strategy that did determine an extension keeps it, so * content still wins over a lying filename. */ private static withResolvedExtension; /** * Load file content from various sources */ private static loadContent; /** * SDK-8: Format an informative placeholder when a file processor fails. * Instead of bare "[Video file: name]" strings, include size, format, and * Describe one keyframe well enough for a model to place it in time. * * The clip's total length rides along because the eighth frame of a * recording means nothing without knowing how long the recording is. * * Explicit units rather than a clock — see `formatKeyframeTimestamp`. An * earlier draft used "0:03" here and the model reported the frame as * appearing at "3:00". * * A timestamp can be missing if extraction and its schedule ever disagree * in length. That should not happen, but an unlabelled frame is better * than one labelled "NaN". */ private static describeKeyframe; /** * the reason for failure so the LLM can acknowledge the attachment. */ private static formatInformativePlaceholder; /** * Extract metadata and printable strings from an unrecognized binary file. * This is the "extract what you can" path for unknown file types. * * Extracts: * - File size (human-readable) * - MIME type / detected format * - First N bytes as hex dump (for identification) * - Printable ASCII/UTF-8 strings found in the binary (like `strings` command) * - Known file signatures that we don't have full processors for * * @param content Raw file buffer * @param detection Detection result (may be "unknown") * @param filename Original filename (if known) * @returns Formatted text summary suitable for LLM consumption */ private static extractBinaryMetadata; /** * Identify known binary file signatures beyond what we can process. * Returns a human-readable description, or null if unrecognized. */ private static identifyBinarySignature; /** * Extract printable ASCII strings from a binary buffer. * Similar to the Unix `strings` utility. * * @param buf Buffer to scan * @param minLength Minimum string length to include (default 4) * @param maxStrings Maximum number of strings to return (default 50) * @returns Array of printable strings found in the binary */ private static extractPrintableStrings; /** * Route to appropriate processor */ private static processFile; /** * Process video file: extract metadata, keyframes, and subtitles via VideoProcessor */ private static processVideoFile; /** * Process audio file: extract metadata, tags, and cover art via AudioProcessor */ private static processAudioFile; /** * Process archive file: list contents and extract metadata via ArchiveProcessor */ private static processArchiveFile; /** * Process Excel/OpenDocument spreadsheet file via ExcelProcessor or OpenDocumentProcessor */ private static processXlsxFile; /** * Process Word/OpenDocument/RTF document via WordProcessor, OpenDocumentProcessor, or RtfProcessor */ private static processDocxFile; /** * Process PowerPoint/OpenDocument presentation via PptxProcessor */ private static processPptxFile; /** * Process SVG file as text content * Uses SvgProcessor for security sanitization (removes XSS vectors) * Returns sanitized SVG markup as text for AI analysis */ private static processSvgAsText; /** * Load file from URL with automatic retry on transient network errors */ private static loadFromURL; /** * Fetch a URL once and retain its response MIME type for detection. */ private static loadUrl; /** * Load file from filesystem path */ private static loadFromPath; /** * Load file from data URI */ private static loadFromDataURI; }