// Type definitions for the SeekySense SDK 1.1.0-rc.1 public bundle export const VERSION: string; /* ------------------------------------------------------------------ profiles */ export type Kind = 'text' | 'image' | 'frame' | 'clip'; export interface Profile { id: string; label?: string; /** 'pipeline' (feature-extraction, any ONNX sentence model) or 'gemma' (EmbeddingGemma multimodal). */ loader?: 'pipeline' | 'gemma'; model: string; dtype?: string; probeFile?: string; visionProbeFile?: string; webgpuRequired?: boolean; dim: number; multilingual?: boolean; indexKinds?: Kind[]; queryKinds?: Array<'text' | 'image' | 'screen'>; queryPrefix?: string; documentPrefix?: string; /** Pooling of 'pipeline' profiles: 'mean' (default) or 'cls'. */ pooling?: 'mean' | 'cls'; /** Pin the backend: 'wasm' keeps an 8-bit model off WebGPU. */ device?: 'wasm'; license?: string; /** Ascending thresholds for levels 0 (standard), 1 (relevant), 2 (high). */ thresholds: { text: number[]; image?: number[]; visual?: number[] }; /** The first 512/256/128 dimensions are usable on their own (needed by features.matryoshka). */ matryoshka?: boolean; downloadMb?: { text: number; vision: number }; minMemoryGb?: number; experimental?: boolean; } export const PROFILES: Record<'gemma-multimodal' | 'granite-multilingual' | 'compact' | 'multilingual-lite', Profile>; export const AUTO_ORDER: string[]; export function defineProfile(partial: Partial & Pick): Profile; export function resolveProfile(input: string | Partial): Profile; export function profileFiles(profile: Profile, opts?: { modelSource?: string; vision?: boolean }): string[]; /* ------------------------------------------------------------------ compatibility */ export interface BrowserInfo { name: string; version: string; major: number; engine: 'blink' | 'gecko' | 'webkit' | 'unknown'; os: string; mobile: boolean; } export interface Capabilities { at?: string; secureContext: boolean; crossOriginIsolated: boolean; online: boolean; esModules: boolean; browser: BrowserInfo; workers: { supported: boolean; shared: boolean }; wasm: { supported: boolean; simd: boolean; threads: boolean }; webgpu: { supported: boolean; adapter: boolean | null; info: { vendor: string; architecture: string; device: string; description: string } | null; fallbackAdapter: boolean; error: string | null; limits?: { maxBufferSizeMb: number | null } }; storage: { indexedDB: boolean; cacheStorage: boolean; opfs: boolean; quotaMb: number | null; usageMb: number | null; persisted: boolean | null }; device: { memoryGb: number | null; cores: number | null; mobile: boolean; touch: boolean; imageBitmap: boolean; camera: boolean; screenCapture: boolean }; /** 1.1 */ concurrency?: { locks: boolean; broadcastChannel: boolean; sharedWorker: boolean; sharedArrayBuffer: boolean }; /** 1.1. `metered`: data saver on, cellular or 2g. */ connection?: { known: boolean; type: string | null; saveData: boolean; metered: boolean }; } export type CompatCode = | 'no-es-modules' | 'no-webassembly' | 'no-secure-context' | 'no-webgpu' | 'no-webgpu-adapter' | 'webgpu-not-probed' | 'webgpu-software-adapter' | 'no-wasm-simd' | 'wasm-single-thread' | 'low-memory' | 'storage-quota-tight' | 'no-cache-storage' | 'offline-without-cache' | 'no-workers' | 'experimental-profile' | 'not-implemented' | 'feature-disabled' | 'no-opfs' | 'no-web-locks' | 'no-broadcast-channel' | 'no-shared-worker' | 'no-indexeddb' | 'gpu-memory' | 'metered-connection' | 'rerank-timeout' | 'static-model-missing' | 'answer-model-too-large' | 'answer-endpoint-missing' | 'learning-share-missing' | 'profile-no-matryoshka' | 'host-not-allowed' | string; export interface ProfileEvaluation { profile: Profile; ok: boolean; reasons: CompatCode[]; warnings: CompatCode[] } export interface Recommendation { profile: Profile | null; evaluation: ProfileEvaluation | null; rejected: Array<{ profile: string; reasons: CompatCode[] }>; mode: 'semantic' | 'lexical' } export interface Hint { code: CompatCode; message: string; action: string } export function detectCapabilities(opts?: { env?: any; adapter?: boolean }): Promise; export function parseBrowser(navigator?: any): BrowserInfo; export function minimumSupport(caps: Capabilities): { lexical: boolean; embeddings: boolean; reasons: CompatCode[] }; export function evaluateProfile(caps: Capabilities, profile: string | Profile): ProfileEvaluation; export function recommendProfile(caps: Capabilities, order?: Array): Recommendation; export function explain(codes: CompatCode[] | { reasons?: CompatCode[]; warnings?: CompatCode[] }, caps?: Partial): Hint[]; export function availableProfiles(caps: Capabilities): Array; export const SUPPORT_MATRIX: { webgpu: Record; wasmSimd: Record }; /* ------------------------------------------------------------------ events */ export type Unsubscribe = () => void; export class Emitter { on(event: string, fn: (payload: any) => void): Unsubscribe; once(event: string, fn: (payload: any) => void): Unsubscribe; off(event: string, fn: (payload: any) => void): void; emit(event: string, payload?: any): void; } /* ------------------------------------------------------------------ embedder */ export interface ImageDataLike { data: Uint8ClampedArray | Uint8Array; width: number; height: number } export interface EmbedTextItem { title?: string; text: string } export interface ProgressEvent { phase: 'text' | 'vision'; loaded: number; total: number; file?: string; status?: string } export interface EmbedderStatus { state: 'idle' | 'loading' | 'ready' | 'error'; mode: 'worker' | 'main' | null; profile: string; backend: 'webgpu' | 'wasm' | null; vision: boolean; visionLoading: boolean; progress: { text: { loaded: number; total: number }; vision: { loaded: number; total: number } }; timings: Record; error: { message: string; code: string | null } | null; } export interface EmbedderOptions { profile: string | Profile; libraryUrl?: string; /** Pre-loaded Transformers.js module (main thread only; disables the worker). */ library?: any; modelSource?: string; engineUrl?: string; workerUrl?: string; baseUrl?: string; useWorker?: boolean; debug?: boolean; } /** Minimal contract for a custom engine passed as `embedder` to createSeekySense. */ export interface EmbedderLike { init(opts?: { withVision?: boolean }): Promise; embedText(items: Array, opts?: { role?: 'query' | 'document'; maxItems?: number }): Promise; embedImage?(image: ImageDataLike): Promise; embedVideo?(frames: ImageDataLike[], duration: number): Promise; status(): any; on?(event: string, fn: (payload: any) => void): Unsubscribe; dispose?(): void; } export class Embedder extends Emitter implements EmbedderLike { constructor(opts: EmbedderOptions); readonly profile: Profile; readonly ready: boolean; status(): EmbedderStatus; init(opts?: { withVision?: boolean }): Promise; loadVision(): Promise; embedText(items: Array, opts?: { role?: 'query' | 'document'; maxItems?: number }): Promise; embedImage(image: ImageDataLike): Promise; embedVideo(frames: ImageDataLike[], duration: number): Promise; webgpuAvailable(): Promise; isCached(opts?: { vision?: boolean }): Promise; clearCache(): Promise; downloadPlan(opts?: { vision?: boolean }): { files: string[]; megabytes: number }; dispose(): void; } export const DEFAULT_LIBRARY_URL: string; export const DEFAULT_MODEL_SOURCE: string; /* ------------------------------------------------------------------ stores */ export interface Entry { key: string; id: string; kind: Kind; q: Int8Array | null; scale: number; hash: string; record?: R; updatedAt: number; } export interface UpsertInput { key?: string; id: string; kind?: Kind; vector: Float32Array | ArrayLike | null; hash?: string; record?: R } export interface StoreMeta { profile: string; dim: number } export interface StoreHit { key: string; id: string; kind: Kind; score: number; record?: R } export class VectorStore { meta: StoreMeta | null; open(meta: StoreMeta): Promise<{ reset: boolean; reason?: string; loaded?: number }>; readonly size: number; has(key: string): boolean; get(key: string): Entry | undefined; entries(): IterableIterator>; upsert(entries: Array | Entry>): Promise; remove(keys: Iterable): Promise; clear(): Promise; scoreAll(query: Float32Array): { keys: string[]; scores: Float32Array } | null; getMeta(key: string): Promise; setMeta(key: string, value: any): Promise; close(): Promise; } export class MemoryVectorStore extends VectorStore { constructor(); byId(id: string): Entry[]; pending(): string[]; matrix(): { keys: string[]; data: Int8Array; scales: Float32Array; dim: number; count: number }; search(query: Float32Array, opts?: { limit?: number; filter?: (e: Entry) => boolean; minScore?: number }): StoreHit[]; vectorOf(key: string): Float32Array | null; exportSnapshot(opts?: { records?: boolean; extra?: Record }): Uint8Array; importSnapshot(input: Uint8Array | ArrayBuffer | Snapshot, opts?: { replace?: boolean }): Promise<{ added: number; skipped: number; header: any }>; } export interface Backend { open(): Promise; getAll(collection: string): Promise; putMany(rows: any[]): Promise; deleteMany(collection: string, keys: string[]): Promise; clear(collection: string): Promise; getMeta(collection: string): Promise; setMeta(collection: string, value: any): Promise; close(): Promise; } export class MemoryBackend implements Backend { kvGet(key: string): Promise; kvSet(key: string, value: any): Promise; open(): Promise; getAll(collection: string): Promise; putMany(rows: any[]): Promise; deleteMany(collection: string, keys: string[]): Promise; clear(collection: string): Promise; getMeta(collection: string): Promise; setMeta(collection: string, value: any): Promise; close(): Promise; } export class IDBBackend implements Backend { constructor(dbName?: string, opts?: { indexedDB?: IDBFactory }); open(): Promise; getAll(collection: string): Promise; putMany(rows: any[]): Promise; deleteMany(collection: string, keys: string[]): Promise; clear(collection: string): Promise; getMeta(collection: string): Promise; setMeta(collection: string, value: any): Promise; close(): Promise; kvGet(key: string): Promise; kvSet(key: string, value: any): Promise; /** Version the database had before this open upgraded it (undefined when no upgrade ran). */ upgradedFrom?: number; static destroy(dbName?: string, idb?: IDBFactory): Promise; } export class IndexedDBVectorStore extends MemoryVectorStore { constructor(opts: { collection: string; dbName?: string; backend?: Backend; persistRecords?: boolean }); } export interface RemoteStoreApi { search(query: number[], opts: { limit: number; kind: Kind | null }): Promise>; upsert?(rows: Array<{ key: string; id: string; kind: Kind; hash: string; vector: number[]; record?: R }>): Promise; remove?(keys: string[]): Promise; clear?(): Promise; hashes?(): Promise>; meta?: { get(key: string): Promise; set(key: string, value: any): Promise }; } export class RemoteVectorStore extends VectorStore { constructor(api: RemoteStoreApi); search(query: Float32Array, opts?: { limit?: number; kind?: Kind | null }): Promise[]>; } /* ------------------------------------------------------------------ collection */ export type Match = 'meaning' | 'words' | 'both' | 'none' | 'visual'; export type SearchMode = 'auto' | 'hybrid' | 'semantic' | 'lexical'; export interface Hit { id: string; record: R; /** dense + 0.12 × word evidence; use for ordering, not as a probability. */ score: number; dense: number | null; words: number; /** −1 below the standard threshold, 0 standard, 1 relevant, 2 high. */ level: number; match: Match; below?: boolean; explain?: HitExplanation; } export interface SearchResult { query?: string; mode: 'hybrid' | 'semantic' | 'lexical' | 'visual' | 'none'; reason: string | null; hits: Hit[]; total?: number; took: number; /** Some records are not embedded yet (engine was away): they are matched by words only. */ partial: boolean; expanded?: Record; /** Steps that actually ran, in order, with their time. */ pipeline?: PipelineStep[]; } export interface SearchOptions { limit?: number; level?: 0 | 1 | 2; mode?: SearchMode; wait?: boolean; filter?: (record: R) => boolean; fallback?: number; lexicalMin?: number; /** Force one rung of the engine ladder for this call. */ tier?: 'auto' | 'lexical' | 'static' | 'transformer'; /** Add `explain` to every hit. */ explain?: boolean; /** Per-call feature overrides. Shorthand keys also work: `{ rerank: false }`. */ features?: FeaturePatch; matryoshka?: FeaturePatch['matryoshka']; binary?: FeaturePatch['binary']; queryQueue?: FeaturePatch['queryQueue']; glossary?: FeaturePatch['glossary']; rules?: FeaturePatch['rules']; queryFilters?: FeaturePatch['queryFilters']; rerank?: FeaturePatch['rerank']; answer?: FeaturePatch['answer']; } export interface UpsertStats { added: number; updated: number; unchanged: number; embedded: number; pending: number; removed?: number } export interface CollectionOptions { fields?: (record: R) => { title?: string; text?: string; image?: ImageDataLike | Blob | string | HTMLImageElement | HTMLCanvasElement | ImageBitmap | null }; keywords?: (record: R, doc: { title?: string; text?: string }, id: string) => string; id?: (record: R) => string | number; store?: 'memory' | 'indexeddb' | VectorStore; persistRecords?: boolean; lexical?: boolean; batchSize?: number; /** Per-collection feature overrides (only features whose scopes include 'collection'). */ features?: FeaturePatch; } export class Collection extends Emitter { readonly name: string; readonly store: VectorStore; readonly lexical: LexicalIndex | null; readonly records: Map; readonly size: number; open(): Promise<{ reset: boolean; reason?: string }>; has(id: string | number): boolean; get(id: string | number): R | undefined; upsert(records: R[], opts?: { wait?: boolean; force?: boolean; signal?: AbortSignal }): Promise; remove(ids: Array): Promise; sync(records: R[], opts?: { wait?: boolean }): Promise; applyChanges(changes: { upserts?: R[]; deletes?: Array; cursor?: any }, opts?: { wait?: boolean }): Promise; getCursor(): Promise; reindex(opts?: { wait?: boolean }): Promise; clear(): Promise; pending(): string[]; embedPending(): Promise; search(query: string, opts?: SearchOptions): Promise>; searchByImage(image: ImageDataLike | Blob | string | HTMLImageElement | HTMLCanvasElement | ImageBitmap, opts?: { text?: string; weight?: number; limit?: number; level?: 0 | 1 | 2; filter?: (record: R) => boolean; kinds?: Kind[] }): Promise>; export(opts?: { records?: boolean; extra?: Record }): Promise; import(bytes: Uint8Array | ArrayBuffer, opts?: { replace?: boolean }): Promise<{ added: number; skipped: number; header: any }>; features(callPatch?: FeaturePatch | null): FeatureStates; configure(features: FeaturePatch | null): FeatureStates; stats(): { collection: string; records: number; vectors: number; pending: number; lexical: number; profile: string | null; engine: EngineState }; close(): Promise; } /* ------------------------------------------------------------------ feature control (1.1) */ /** * Every optional capability, off by default. With no `features` and no `preset` the SDK behaves exactly like 1.0. * A requested feature that cannot run on a device falls back and reports why in `seeky.features()`. */ export interface FeatureOptions { /** Vector scoring. Default js on the main thread. Fallback: js. Scope: instance. */ scoring: { backend: 'auto' | 'js' | 'wasm' | 'webgpu'; inWorker: boolean; /** rows above which 'auto' may use WebGPU (default 200000) */ webgpuMinRows: number }; /** Search on the first `dims` dimensions, re-rank the best `rerankTop` with full vectors. Needs profile.matryoshka. `storeFull` change needs reindex. */ matryoshka: { enabled: boolean; dims: 64 | 128 | 256 | 512; rerankTop: number; storeFull: boolean }; /** One-bit prefilter then int8 rescoring. 'auto': only above `minRows`. */ binary: { enabled: boolean | 'auto'; minRows: number; candidates: number }; /** One model for every tab. 'auto' picks leader-tab (Web Locks + BroadcastChannel), then shared-worker. */ sharedEngine: { enabled: boolean; strategy: 'auto' | 'leader-tab' | 'shared-worker'; scope: string }; /** Where model files live and when they are fetched. Default: Cache Storage, on start(). */ modelCache: { storage: 'auto' | 'cache' | 'opfs'; prefetch: 'off' | 'manual' | 'idle'; allowMetered: boolean; resume: boolean; persist: boolean }; /** Debounce, cancel stale queries, cache query vectors. */ queryQueue: { enabled: boolean; debounceMs: number; cancelStale: boolean; lruSize: number; warmup: boolean }; /** Engine ladder. Default ['lexical', 'transformer']. Adding 'static' needs reindex. Array shorthand accepted. */ tiers: { order: Array<'lexical' | 'static' | 'transformer'>; staticModel: string; staticThresholds: number[] | null }; similar: { enabled: boolean }; glossary: { enabled: boolean; source: string | Record | null; rewrite: boolean; bidirectional: boolean }; rules: { enabled: boolean; items: object[] }; queryFilters: { enabled: boolean; fields: Record; locale: string }; /** Cross-encoder on the first `top` hits. Past `timeoutMs` the first-pass order is returned. */ rerank: { enabled: boolean; model: string; top: number; timeoutMs: number }; /** Explicit consent: never in a preset. With engine/fallback 'endpoint', passages leave the device. */ answer: { enabled: boolean; engine: 'local' | 'browser' | 'endpoint'; model: string; endpoint: string | ((request: any) => any) | null; maxTokens: number; language: string; fallback: 'none' | 'endpoint' }; /** Explicit consent: never in a preset. */ learning: { enabled: boolean; scope: 'user' | 'tenant'; halfLifeDays: number; maxBoost: number; share: { export: Function; import: Function } | null }; privacy: { networkProof: boolean; allowHosts: string[] | null }; sync: { crossTab: boolean; deltaSnapshots: boolean; shards: string | object | null }; } export type FeatureName = keyof FeatureOptions; export type FeatureConfig = FeatureOptions; /** A patch: any subset of options; `true`/`false` is shorthand for { enabled }, an array for tiers.order. */ export type FeaturePatch = { [K in FeatureName]?: Partial | boolean | (K extends 'tiers' ? Array<'lexical' | 'static' | 'transformer'> : never) }; export type PresetName = 'compat' | 'balanced' | 'max'; export type FeatureScope = 'instance' | 'collection' | 'call'; export interface FeatureState { requested: boolean; active: boolean; implemented: boolean; /** What an 'auto' option resolved to on this device. */ backend: string | null; reason: CompatCode | null; reasons: CompatCode[]; /** What runs instead when requested but not active. */ fallback: string | null; downloadMb: number | null; hosts: string[]; sendsData: boolean; phase: string; options: FeatureOptions[K]; } export type FeatureStates = { [K in FeatureName]: FeatureState }; export interface FeatureIssue { path: string; message: string; allowed?: string } export class FeatureConfigError extends Error { code: 'invalid-features'; issues: FeatureIssue[] } export interface PlanItem { feature: 'engine' | FeatureName; megabytes: number | null; hosts: string[]; sendsData: boolean; active: boolean; reason: CompatCode | null; profile?: string | null; files?: string[]; cached?: boolean | null } export interface Plan { items: PlanItem[]; hosts: string[]; totalMb: number; unknownSizes: string[]; sendsData: boolean } export interface ConfigureResult { applied: FeatureName[]; details: Partial>; needsReindex: FeatureName[]; needsDownload: PlanItem[]; features: FeatureStates } export interface PipelineStep { step: 'lexical' | 'embed' | 'int8' | 'remote' | 'merge' | string; ms: number; [extra: string]: any } export interface HitExplanation { dense: number | null; thresholds: number[] | null; lexical: { bm25: number; best: number; coverage: number; evidence: number; strongAt: number }; /** meaning + words (+ rules + clicks) = score. */ contributions: { meaning: number; words: number; rules: number; clicks: number; rerank: number | null }; } export const FEATURE_NAMES: FeatureName[]; export const PRESETS: Record; export function validateFeatures(patch: FeaturePatch | null | undefined, opts?: { scope?: FeatureScope }): { value: FeaturePatch; issues: FeatureIssue[] }; /** PRESETS.max minus what this device rejects. */ export function recommendFeatures(caps: Capabilities, ctx?: { profile?: Profile | null }): { features: FeaturePatch; dropped: Array<{ feature: FeatureName; reasons: CompatCode[] }> }; export function describeFeatures(): Array<{ name: FeatureName; title: string; rf: string; phase: string; implemented: boolean; consent: boolean; scopes: FeatureScope[]; fallback: string; defaults: object; options: Record; reindex: string[] }>; /* ------------------------------------------------------------------ SDK */ export type EngineState = 'idle' | 'loading' | 'ready' | 'unavailable'; export interface SeekySenseOptions extends Partial> { profile?: 'auto' | string | Profile | Array; autoStart?: boolean; name?: string; force?: boolean; embedder?: EmbedderLike; capabilities?: Capabilities; /** Starting point for optional features. Default 'compat' (= 1.0). */ preset?: PresetName | FeaturePatch; /** Per-feature options over the preset. */ features?: FeaturePatch; /** Invalid feature options throw FeatureConfigError (default true); false: warn and ignore. */ strict?: boolean; } export interface Status { version: string; engine: EngineState; mode: 'semantic' | 'lexical'; reason: string | null; profile: string | null; backend: 'webgpu' | 'wasm' | string | null; worker: boolean | null; vision: boolean; progress: EmbedderStatus['progress'] | null; timings: Record | null; error: { message: string; code: string | null } | null; } export class SeekySense extends Emitter { constructor(opts?: SeekySenseOptions); readonly version: string; readonly name: string; readonly profile: Profile | null; readonly embedder: EmbedderLike | null; readonly evaluation: ProfileEvaluation | null; readonly unavailableReason: string | null; capabilities(opts?: { refresh?: boolean }): Promise; resolve(): Promise; start(): Promise; ready(): Promise; engineState(): EngineState; status(): Status; whyNot(): Promise; /** 'compat' | 'balanced' | 'max' | 'custom' */ readonly preset: string; /** State of every feature. Capability reasons need `await capabilities()` first. */ features(): FeatureStates; featureConfig(): FeatureConfig; /** Change features at runtime. Downloads and re-indexing are reported, never started. */ configure(input: { preset?: PresetName | FeaturePatch; features?: FeaturePatch; strict?: boolean }): ConfigureResult; /** Files, hosts and megabytes of the current configuration, before anything is fetched. */ plan(): Promise; on(event: 'features', fn: (r: ConfigureResult) => void): Unsubscribe; collection(name: string, opts?: CollectionOptions): Collection; embed(texts: Array, opts?: { role?: 'query' | 'document' }): Promise; dispose(): Promise; /** Events: 'status' (Status), 'progress' (ProgressEvent), 'ready', 'error', 'resolved', 'vision'. */ on(event: 'status', fn: (s: Status) => void): Unsubscribe; on(event: 'progress', fn: (p: ProgressEvent) => void): Unsubscribe; on(event: string, fn: (payload: any) => void): Unsubscribe; } export function createSeekySense(opts?: SeekySenseOptions): SeekySense; /* ------------------------------------------------------------------ lexical & fusion */ interface LexicalIndex { readonly size: number; has(id: any): boolean; add(id: any, text: string): void; addAll(entries: Iterable<[any, string]>): void; remove(id: any): boolean; clear(): void; search(query: string, opts?: { fuzzy?: boolean; bigramWeight?: number; fuzzyWeight?: number }): { scores: Map; coverage: Map; max: number; expanded: Record; tokens: string[] }; rank(query: string, opts?: { limit?: number; fuzzy?: boolean }): Array<{ id: any; score: number; coverage: number }>; } /* ------------------------------------------------------------------ vectors, snapshot, text */ export function normalize(vec: ArrayLike): Float32Array; export function cosine(a: ArrayLike, b: ArrayLike): number; export function toArray(vec: ArrayLike): number[]; export function toPgvector(vec: ArrayLike): string; export function toBase64(vec: ArrayLike): string; export function fromBase64(b64: string): Float32Array; export interface Snapshot { header: any; dim: number; count: number; scales: Float32Array; data: Int8Array } export function parseSnapshot(input: ArrayBuffer | Uint8Array): Snapshot; export function loadSnapshot(url: string, init?: RequestInit): Promise; export function chunkPages(pages: Array<{ page?: number; text: string }>, opts?: { maxChars?: number; overlap?: number }): Array<{ id: number; page: number; text: string }>; export function chunkText(text: string, opts?: { maxChars?: number; overlap?: number }): Array<{ id: number; page: number; text: string }>; /* ------------------------------------------------------------------ WordPress snapshot ranking, engine helpers */ export namespace imageInput { const QUERY_MAX_SIDE: number; function fitWithin(width: number, height: number, maxSide: number): { width: number; height: number }; function clampRect(rect: { x: number; y: number; w: number; h: number }, width: number, height: number, min?: number): { x: number; y: number; w: number; h: number }; function screenCaptureSupported(): boolean; function bitmapFromFile(file: Blob): Promise; function pickFile(input: HTMLInputElement): Promise; function captureScreenFrame(): Promise; function regionToImageData(bitmap: ImageBitmap | HTMLImageElement, rect: { x: number; y: number; w: number; h: number } | null, maxSide?: number): { imageData: ImageData; preview: string }; function cropImage(bitmap: ImageBitmap, strings?: Record): Promise<{ imageData: ImageData; preview: string; rect: object } | null>; function toImageData(src: any, maxSide?: number): Promise; } /* ================================================================== 1.1: features implemented after phase 0 */ // Interfaces below merge with the declarations above (TypeScript declaration merging). export interface SeekySenseOptions { /** Factory for the local engine; unlike `embedder` it is still wrapped by sharedEngine. */ createEmbedder?: (profile: Profile, opts: SeekySenseOptions) => EmbedderLike; /** A ready StaticEmbedder (tests, custom static models). */ staticEmbedder?: StaticEmbedder; /** fetch used for every SDK request on the main thread (tests, proxies). */ fetch?: typeof fetch; scoringWorkerUrl?: string; sharedWorkerUrl?: string; } export interface Status { shared: { strategy: 'leader-tab' | 'shared-worker'; role?: 'leader' | 'follower' | 'pending'; leader?: string; self?: string; leaderChanges?: number } | null; storage: 'cache' | 'opfs' | null; tiers: { static: 'off' | 'loading' | 'ready' | 'error' }; } export interface SeekySense { /** modelCache.prefetch 'manual': download the model now; same as start(). */ prefetch(): Promise; staticState(): 'off' | 'loading' | 'ready' | 'error'; rerankState(): 'off' | 'loading' | 'ready' | 'error'; /** Replace the glossary used when features.glossary.source is not set. */ setGlossary(source: Record | string): void; /** Needs features.privacy.networkProof. */ networkProof(opts?: { observeAll?: boolean }): NetworkReport; /** Text → object conforming to a JSON schema. Needs features.answer. */ extract(text: string, schema: JsonSchema, opts?: { onToken?: (text: string) => void; signal?: AbortSignal }): Promise>; readonly network: NetworkLog; readonly staticEmbedder: StaticEmbedder | null; readonly reranker: RerankerSpec | null; on(event: 'static' | 'reranker' | 'leader' | 'prefetch' | 'persist' | 'warning', fn: (payload: any) => void): Unsubscribe; } export interface SearchOptions { signal?: AbortSignal; } export interface Hit { /** Cross-encoder score, when the reranker scored this hit. */ rerank?: number; /** Boost from click feedback. */ learned?: number; /** Names of the rules that touched this hit. */ rules?: string[]; pinned?: boolean; } export interface SearchResult { /** Rung of the engine ladder that answered. */ tier?: 'lexical' | 'static' | 'transformer' | 'none'; totalIsEstimate?: boolean; /** Filters read from the query (queryFilters). */ parsed?: { text: string; filters: QueryFilter[] }; /** Glossary terms found in the query. */ glossary?: Array<{ term: string; alternatives: string[] }>; /** Names of the rules applied. */ rules?: string[]; rerank?: { applied: boolean; reason?: string; model?: string; reranked?: number; abstained?: number; ms?: number }; learned?: boolean; shards?: { loaded: number; total: number }; stage?: 'instant' | 'final'; } export interface LiveSearch { update(text: string): void; attach(input: EventTarget & { value: string }): () => void; cancel(): void } export interface Collection { readonly staticStore: MemoryVectorStore | null; /** Needs queryQueue (instance, collection, or `{ queryQueue: true }` here). */ liveSearch(onResults: (result: SearchResult) => void, opts?: SearchOptions & { onError?: (e: Error) => void }): LiveSearch; /** Needs features.similar. No inference. */ similar(id: string | number, opts?: { limit?: number; level?: 0 | 1 | 2; filter?: (record: R) => boolean }): Promise<{ id: string; tier: string; hits: Hit[]; total: number; took: number }>; duplicates(opts?: DuplicateOptions): Promise>; checkDuplicate(record: R, opts?: { threshold?: number; limit?: number; confirm?: DuplicateOptions['confirm']; requireConfirm?: boolean; wait?: boolean }): Promise<{ duplicate: boolean; candidates: Array<{ id: string; record: R; score: number | null; confirmed: boolean | null }>; tier: string; took: number }>; exportDelta(base: Uint8Array | ArrayBuffer, opts?: { records?: boolean; extra?: Record }): Promise; exportShards(opts?: { by?: (record: R) => string; maxRecords?: number; baseUrl?: string }): Promise<{ manifest: ShardManifest; files: Array<{ name: string; bytes: Uint8Array }> }>; loadShards(manifest: string | ShardManifest, opts?: { concurrency?: number; onShard?: (s: any) => void; fetch?: typeof fetch; signal?: AbortSignal }): Promise<{ loaded: number; total: number; records: number; done?: boolean }>; /** Needs features.learning (explicit consent). */ feedback(e: { query: string; id: string | number; type?: 'click' | 'select' | 'dismiss'; dense?: number }): Promise; suggestThresholds(opts?: { minEvents?: number }): Promise<{ suggested: number[] | null; current: number[]; reason: string | null; samples: { chosen: number; dismissed: number; needed?: number } }>; resetLearning(): Promise; syncLearning(): Promise<{ sent: number; received: number }>; /** Needs features.answer (explicit consent). */ answer(question: string, opts?: { limit?: number; level?: 0 | 1 | 2; onToken?: (text: string) => void; signal?: AbortSignal; language?: string }): Promise>; } export interface DuplicateOptions { threshold?: number; confirm?: string[] | { fields: string[]; mode?: 'any' | 'all' } | ((a: R, b: R) => boolean); requireConfirm?: boolean; candidates?: number; batch?: number; limit?: number; onProgress?: (p: { done: number; total: number }) => void; signal?: AbortSignal; } export interface DuplicatePair { a: string; b: string; score: number; confirmed: boolean | null } export interface DuplicateResult { groups: Array<{ ids: string[]; records: R[]; score: number; pairs: DuplicatePair[] }>; pairs: DuplicatePair[]; scanned: number; threshold?: number; tier?: string; took: number } export interface ShardManifest { format: 'seekysense-shards'; version: number; collection: string; profile: string; dim: number; createdAt: string; shards: Array<{ url: string; label: string; id: string; count: number; bytes: number }> } export interface FeedbackEvent { query: string; key: string; id: string; type: 'click' | 'select' | 'dismiss'; dense: number | null; at: number; origin: 'local' | 'tenant' } export interface AnswerResult { question: string; /** null when refused. */ answer: string | null; refused: boolean; /** 'no-evidence' (nothing retrieved, no generation), 'model-refused', 'uncited-sentences', or null. */ reason: string | null; citations: Array<{ n: number; id: string; record: R }>; /** Sentences without a citation. */ uncited: string[]; /** Every sentence carries a citation to a retrieved record (not a check that the citation is the right one). */ grounded: boolean; passages: Array<{ n: number; id: string; record: R; score: number; text: string }>; engine: 'local' | 'browser' | 'endpoint' | null; model?: string | null; raw?: string; took: number; search: { mode: string; tier?: string; total?: number }; } export type JsonSchema = { type?: string; properties?: Record; required?: string[]; enum?: any[]; items?: JsonSchema }; export interface ExtractResult { data: T | null; valid: boolean; errors: string[]; confidence: number; engine: string; raw: string; took: number } /* scoring */ export interface VectorStore { version?: number } export interface MemoryVectorStore { version: number; matrixFor(opts?: { kinds?: Kind[] | null; dims?: number | null }): { keys: string[]; rowOf: Map; data: Int8Array; scales: Float32Array; dim: number; count: number; version: number }; snapshotId(): string; exportDelta(base: Uint8Array | ArrayBuffer | Snapshot, opts?: { records?: boolean; extra?: Record }): Uint8Array; } /* static embeddings */ interface StaticEmbedder { readonly ready: boolean; readonly dim: number; info?: { model: string; license: string; dim: number; vocab: number; thresholds: { text: number[] } | null; loadMs: number }; files(): string[]; load(): Promise; embed(items: Array): Float32Array[]; } /* query tools */ export interface QueryFilter { field: string; op: '<' | '>' | 'between' | '=' | 'year'; value: any; value2?: any; source: string } interface Glossary { readonly size: number; expand(query: string, opts?: { maxVariants?: number }): { matches: Array<{ term: string; alternatives: string[] }>; variants: string[]; semantic: string }; } export interface Rule { id?: string; when?: string | string[] | RegExp | ((query: string) => boolean); pin?: Array; boost?: number; match?: ((record: R, id: string) => boolean) | Record | string[]; exclude?: ((record: R, id: string) => boolean) | Record | string[] } /* similar */ /* rerank */ export interface RerankerSpec { id: string; model: string; dtype: string; fileName?: string; megabytes: number | null; languages: string[] | null; license?: string } /* privacy */ export interface NetworkEntry { url: string; host: string | null; finalHost?: string | null; method?: string; status?: number; bytes?: number | null; sentBody?: boolean; context: string; feature: string; at: number; blocked?: boolean; afterReady?: boolean; kind?: string } export interface NetworkReport { since: string; readyAt: string | null; requests: NetworkEntry[]; blocked: NetworkEntry[]; hosts: string[]; afterReady: NetworkEntry[]; quietSinceReady: boolean; sentBodies: number; page?: Array<{ url: string; host: string | null; type: string; bytes: number; at: number }> } interface NetworkLog { entries: NetworkEntry[]; record(e: Partial): void; markReady(): void; reset(): void; report(): NetworkReport } /* learning */ /* answers */ export interface GeneratorSpec { id: string; model: string; dtype: string; megabytes: number | null; languages?: string; license?: string; noThink?: boolean } /* UI: also exported from '@seekysense/sdk/ui' */ export interface SearchSnapshot { query: string; result: SearchResult | null; hits: Hit[]; mode: string; tier: string; loading: boolean; error: Error | null; status: Status; stage: 'instant' | 'final' | null } export interface SearchStore { subscribe(fn: () => void): () => void; getSnapshot(): SearchSnapshot; setQuery(text: string): void; refresh(): void; destroy(): void } export function createSearchStore(collection: Collection, opts?: SearchOptions & { live?: boolean | 'auto' }): SearchStore; export function attachGridFilter(collection: Collection, opts: { input: EventTarget & { value: string }; onRows: (records: R[] | null, snapshot: SearchSnapshot) => void; onResult?: (r: SearchResult) => void; minLength?: number } & SearchOptions): () => void;