/** * Store model bytes without downloading them. * * For an app that already has the bytes — from a file input, or from a * bundle it unpacked — and wants the next load to find them cached. * * @param url The URL to key the entry under. * @param bytes The model bytes. * @param cacheName Cache Storage bucket name. * @returns `true` when the entry was stored, `false` without Cache Storage. */ export declare function cacheModelBytes(url: string, bytes: Uint8Array, cacheName?: string): Promise; /** * Drop cached models. * * @param url A specific model to evict; omit to delete the whole bucket. * @param cacheName Cache Storage bucket name. * @returns `true` when something was deleted. */ export declare function clearModelCache(url?: string, cacheName?: string): Promise; /** * The bytes are not a compact model, or use a newer layout. * * Separate from {@link ModelLoadError} because the fix is different: a * `.onnx` file handed to the compact reader is a wiring mistake, not a * broken model. */ export declare class CompactFormatError extends TabularError { constructor(message: string, options?: ErrorOptions); } /** What the file holds. */ export declare type CompactKind = "linear" | "tree_ensemble"; /** * A compact model, loaded and ready to answer. * * @example * ```ts * const predictor = await CompactPredictor.create("/models/risk.tmc"); * const { labels, probabilities } = await predictor.predict([[5.1, 3.5, 1.4, 0.2]]); * ``` */ export declare class CompactPredictor { private readonly header; private readonly arrays; /** What is loaded. */ readonly info: CompactPredictorInfo; private constructor(); /** * Load a `.tmc` file. * * @param source A URL, or the bytes when the app already has them. * @param requestInit `fetch` options, when `source` is a URL. * @returns The loaded predictor. * @throws {@link ModelFetchError} when a URL cannot be read. * @throws {@link CompactFormatError} when the bytes are not a compact * model, or use a layout newer than this reader. */ static create(source: string | ArrayBuffer | Uint8Array, requestInit?: RequestInit): Promise; /** * Predict for a batch of rows. * * @param rows One array of feature values per row, in training column * order. A single row is still wrapped: `[[...]]`. * @returns Labels, class scores when the model is a classifier, and the * call's duration. * @throws {@link FeatureShapeError} when the batch is empty, ragged, or * the wrong width. */ predict(rows: readonly FeatureRow[]): Promise; /** Releasing nothing, so callers can swap predictors without branching. */ dispose(): Promise; /** * Apply the folded scaler, when the export had one. * * @param row The raw feature values. * @param width How many there are. * @returns The values the model was trained on. */ private preprocess; /** * Score one row against the coefficient matrix. * * @param row The prepared feature values. * @returns One raw score per output. */ private linearScores; /** * Walk every tree and average what the leaves hold. * * A leaf is marked by a negative `feature` entry, which also carries * its slot in the value array — so the walk needs no second lookup and * the file stores values only for leaves. * * **The comparison runs in float32** (`Math.fround`), because that is * what scikit-learn does: it casts its input to float32 before * traversing, so a threshold like 5.099999904632568 — a float32 value * widened for storage — and an input of 5.1 compare *equal* and go * left. Comparing in float64 sends that row right instead, which on an * iris forest changed one tree's vote and moved a probability by 0.05. * * @param row The prepared feature values. * @returns One averaged score per output. */ private treeScores; /** * Turn raw scores into labels and probabilities. * * @param scores One score array per row. * @returns Labels and probabilities in the shape the ONNX route uses, * so an app can swap runtimes without touching its own code. That * includes the label's **type**: an integer class comes back as a * number here exactly as ONNX returns it, because two routes over one * model that disagree on `0` versus `"0"` break the day someone * switches. */ private finish; } /** What a loaded compact model is. */ export declare interface CompactPredictorInfo { /** Which reader path the file uses. */ readonly kind: CompactKind; /** Class labels in score-column order; empty for a regressor. */ readonly classes: readonly string[]; /** Values expected per row. */ readonly numFeatures: number; /** Column order recorded at training time, when the export had one. */ readonly featureNames: readonly string[]; /** Trees in the ensemble; `0` for a linear model. */ readonly numTrees: number; /** Whether the model produces class scores. */ readonly isClassifier: boolean; /** Class name of the exported estimator. */ readonly estimator: string; } /** * Where the runtime's binaries were said to live. * * Read by the ONNX predictor just before it creates a session, which is * the first moment the runtime exists to be configured. * * @returns The configured directory, or `undefined` when none was set. */ export declare function configuredOrtAssetPath(): string | undefined; /** * Point ONNX Runtime Web at locally served WebAssembly binaries. * * Call once, before creating any predictor. * * @example * ```ts * configureOrtAssets("/ort/"); * const predictor = await TabularPredictor.create("/models/classifier.onnx"); * ``` * * @param basePath Directory the binaries are served from, with a trailing * slash. Copy them there at build time — for Vite, from * `node_modules/onnxruntime-web/dist/`. */ export declare function configureOrtAssets(basePath: string): void; /** Cache Storage bucket used when the caller does not name one. */ export declare const DEFAULT_MODEL_CACHE = "tempest-tabular-models"; /** * Execution providers used when the caller does not choose. * * WebAssembly only, and deliberately: scikit-learn graphs are `ai.onnx.ml` * operators, which the WebGPU backend does not implement. There is no * speed left on the table here — a 10-tree forest predicts a row in about * 0.05 ms in Chromium. */ export declare const DEFAULT_TABULAR_PROVIDERS: readonly string[]; /** The package manifest, as written by `edge_pipeline`. */ export declare interface EdgeManifest { readonly schema_version: number; readonly name: string; readonly version: string; readonly created_at: string; readonly sdk_version: string; readonly estimator: string; readonly model: ManifestModelFile; readonly input: ManifestInput; readonly output: ManifestOutput; readonly verified: boolean | null; /** Every file a runtime can load. Absent on packages written before v0.194. */ readonly runtimes?: readonly ManifestRuntime[]; /** Absent on packages built straight from a fitted estimator. */ readonly source?: ManifestSource; readonly baseline_file: string | null; readonly baseline_samples: number; } /** One row of feature values, in the column order the model was trained on. */ export declare type FeatureRow = readonly number[]; /** The rows do not match what the model expects. */ export declare class FeatureShapeError extends TabularError { constructor(message: string, options?: ErrorOptions); } /** * Read a package's manifest. * * Cheap: it is a few hundred bytes, so an app can check for a new version * without downloading a model it may already have. * * @example * ```ts * const manifest = await fetchEdgeManifest("/models/risk/"); * if (manifest.version !== localStorage.getItem("risk-version")) { * // a new model was published * } * ``` * * @param directoryUrl URL of the package directory, with or without a * trailing slash. A full URL to the manifest file also works. * @param requestInit `fetch` options. * @returns The parsed manifest. * @throws {@link ModelFetchError} when the manifest cannot be read, or when * its `schema_version` is newer than this reader understands — loading it * anyway would risk misreading the field that defines column order. */ export declare function fetchEdgeManifest(directoryUrl: string, requestInit?: RequestInit): Promise; /** * Fetch the model bytes, preferring the on-device copy. * * @example * ```ts * const bytes = await fetchModelBytes("/models/classifier-v3.onnx"); * const predictor = await TabularPredictor.create(bytes); * ``` * * @param url Where the model lives. * @param options Cache bucket, revalidation and `fetch` options. * @returns The model bytes. * @throws {@link ModelFetchError} when the model is neither cached nor * reachable — which is the "offline and never warmed" case, and the * message says so. */ export declare function fetchModelBytes(url: string, options?: ModelCacheOptions): Promise; /** The session ran but its outputs could not be read. */ export declare class InferenceError extends TabularError { constructor(message: string, options?: ErrorOptions); } /** * Whether a model is already on the device. * * Useful for showing "available offline" in the UI, and for deciding * whether to prefetch on a metered connection. * * @param url The model URL. * @param cacheName Cache Storage bucket name. * @returns `true` when the bytes are cached. */ export declare function isModelCached(url: string, cacheName?: string): Promise; /** A package loaded and ready to answer. */ export declare interface LoadedEdgePackage { /** What was published. */ readonly manifest: EdgeManifest; /** The running model, whichever runtime read it. */ readonly predictor: PredictorLike; /** Which reader was used. */ readonly runtime: TabularRuntime; /** Column order the rows must follow. */ readonly featureNames: readonly string[]; /** Class names behind each probability column. */ readonly classes: readonly string[]; /** * Map a prediction's scores onto class names. * * @param probabilities One row of scores. * @returns Name/score pairs, highest first. */ readonly explain: (probabilities: readonly number[]) => { name: string; score: number; }[]; } /** * Load a whole edge package: manifest, model, and the names to read it by. * * @example * ```ts * const pkg = await loadEdgePackage("/models/risk/"); * * console.log(pkg.featureNames); // ["age", "income", "tenure", "score", "visits"] * * const { probabilities } = await pkg.predictor.predict([[41, 5200, 3, 0.82, 12]]); * console.log(pkg.explain(probabilities[0]!)); // [{ name: "approved", score: 0.91 }, ...] * ``` * * @param directoryUrl URL of the package directory. * @param options Predictor options plus caching. * @returns The loaded package. * @throws {@link ModelFetchError} when the manifest or model cannot be read. */ export declare function loadEdgePackage(directoryUrl: string, options?: LoadEdgePackageOptions): Promise; /** Options for {@link loadEdgePackage}. */ export declare interface LoadEdgePackageOptions extends TabularPredictorOptions { /** Cache the model bytes for offline use. `true` by default. */ readonly cache?: boolean | ModelCacheOptions; /** * Which reader to use. * * `"auto"` (the default) takes the compact form when the package has * one, because it answers without downloading a WebAssembly runtime. * Force `"onnx"` when the app already ships ONNX for something else — * then the runtime is already paid for and ONNX covers more estimators. */ readonly runtime?: TabularRuntime | "auto"; } /** What the graph expects per row. */ export declare interface ManifestInput { readonly name: string; readonly features: number; /** Column order used at training time. */ readonly feature_names: readonly string[]; } /** The graph file and how to check you got it whole. */ export declare interface ManifestModelFile { readonly file: string; readonly sha256: string; readonly bytes: number; readonly gzip_file: string | null; readonly gzip_bytes: number | null; readonly opset: number; readonly dtype: string; } /** What the graph answers. */ export declare interface ManifestOutput { readonly is_classifier: boolean; readonly label_output: string; readonly probability_output: string | null; /** Class labels in score-column order. */ readonly classes: readonly string[]; } /** * One file in the package a runtime can load. * * A package may carry the same model twice — as ONNX, which any runtime * reads at the cost of a 25.6 MB WebAssembly download, and as the compact * format, which needs no runtime. The list is what lets the browser pick * by what it already ships. */ export declare interface ManifestRuntime { readonly kind: "onnx" | "compact" | string; readonly file: string; readonly bytes: number; readonly gzip_file: string | null; readonly gzip_bytes: number | null; readonly sha256: string; } /** * Where the packaged model came from, when it came from an existing * artifact. * * Present when the package was built with `edge_pipeline_from_pickle`: the * `.pkl` never reaches the browser (a pickle is a Python program, not * data), but its name and digest travel in the manifest, so a model * answering in a tab can be traced back to the file that produced it. */ export declare interface ManifestSource { readonly file: string; readonly kind: string; readonly sha256: string; readonly bytes: number; readonly sklearn_version: string; readonly warnings: readonly string[]; } /** Options for {@link fetchModelBytes}. */ export declare interface ModelCacheOptions { /** Cache Storage bucket name. */ readonly cacheName?: string; /** * Go to the network first and fall back to the cache. * * For a URL that serves "whatever is current" rather than a pinned * version. Costs a round trip on every load when online. */ readonly revalidate?: boolean; /** `fetch` options, e.g. credentials for a private model endpoint. */ readonly requestInit?: RequestInit; } /** * The model bytes could not be fetched or read from the cache. * * Distinct from {@link ModelLoadError}: this one means the app is offline * and nothing was cached, which is a deployment problem, not a model * problem. */ export declare class ModelFetchError extends TabularError { constructor(message: string, options?: ErrorOptions); } /** The model bytes could not be loaded into a session. */ export declare class ModelLoadError extends TabularError { constructor(message: string, options?: ErrorOptions); } /** * The WebAssembly binaries ONNX Runtime Web may request. * * Which one is fetched depends on the browser's threading and SIMD support, * so an app that must work everywhere ships all of them. Chromium with the * default entry point fetched the `jsep` build. */ export declare const ORT_WASM_ASSETS: readonly string[]; /** * The URLs a service worker should precache for offline inference. * * The model file is not included: it is cached by * {@link fetchModelBytes} on first use, under its own bucket. * * @example * ```ts * installPrecache([...ortAssetUrls("/ort/"), "/index.html"]); * ``` * * @param basePath Directory the binaries are served from. * @returns Absolute-from-root URLs for every runtime asset. */ export declare function ortAssetUrls(basePath: string): string[]; /** * A predicted class label. * * scikit-learn classifiers export an int64 label tensor, which ONNX Runtime * Web surfaces as `bigint`. Those are converted to `number` — a class index * never approaches `Number.MAX_SAFE_INTEGER`, and leaving `bigint` in the * result would break `JSON.stringify` and every `=== 1` comparison a caller * writes. A model trained on string labels keeps them as strings. */ export declare type PredictedLabel = number | string; /** * The shape both readers share. * * `TabularPredictor` (ONNX) and `CompactPredictor` (runtime-free) answer * with the same object, so an app can switch routes without touching a * line of its own code. */ export declare interface PredictorLike { predict(rows: readonly FeatureRow[]): Promise; dispose(): Promise; } /** * Errors thrown by the tabular inference module. * * Each one exists because the underlying failure is unreadable on its own: * ONNX Runtime reports a missing operator registration, and the actual cause * is an import path chosen three files away. * * Every subclass sets `name` to a **literal** string rather than to * `new.target.name`. Measured in a real build: the minifier renames the * class, so the derived form ships as `error.name === "t"` — useless in a * log and in any consumer that branches on the name. */ /** Base class for every error this module throws. */ export declare class TabularError extends Error { constructor(message: string, options?: ErrorOptions); } /** * Types for browser inference over tabular models exported from scikit-learn. */ /** Anything `InferenceSession.create` accepts as a model. */ export declare type TabularModelSource = string | ArrayBufferLike | Uint8Array; /** One batch of predictions. */ export declare interface TabularPrediction { /** Predicted class or regressed value per row. */ readonly labels: readonly PredictedLabel[]; /** Class scores per row; empty for a regressor. */ readonly probabilities: readonly (readonly number[])[]; /** Rows predicted. */ readonly numRows: number; /** Wall-clock inference duration in milliseconds. */ readonly ms: number; } /** * A loaded tabular model, ready to answer. * * @example * ```ts * const predictor = await TabularPredictor.create("/models/classifier.onnx"); * const { labels, probabilities } = await predictor.predict([[5.1, 3.5, 1.4, 0.2]]); * ``` */ export declare class TabularPredictor { private readonly runtime; private readonly session; /** What is loaded and how it is configured. */ readonly info: TabularPredictorInfo; private constructor(); /** * Load a model and describe its graph. * * @param source A URL string, or the model bytes (which is what an * offline app passes, having read them from the cache). * @param options Providers, warm-up and pass-through session options. * @throws {@link UnsupportedGraphError} when the runtime build lacks the * `ai.onnx.ml` operators — the WebGPU entry point does. * @throws {@link ModelLoadError} for any other load failure. */ static create(source: TabularModelSource, options?: TabularPredictorOptions): Promise; /** * Run one throwaway inference so the first real call is not the slow one. * * Skipped when the graph does not declare a feature count, since there * is no shape to synthesise. * * @tempest-limits empty-catch — a warm-up that cannot run is not a reason to * refuse to serve. The synthetic all-zero row can be rejected by a graph that * expects a different dtype or a categorical encoding, and that says nothing * about the real rows the caller will send; the only cost of the failure is * that the first real inference pays the lazy-init it would have paid anyway. */ warmUp(): Promise; /** * Predict for a batch of rows. * * @param rows One array of feature values per row, in training column * order. A single row is still wrapped: `[[...]]`. * @returns Labels, class scores when the model produces them, and the * call's duration. * @throws {@link FeatureShapeError} when the batch is empty, ragged, or * the wrong width — checked here so the failure names the mismatch * instead of surfacing as an opaque runtime error. * @throws {@link InferenceError} when the session runs but its outputs * cannot be read. */ predict(rows: readonly FeatureRow[]): Promise; /** * Release the session's memory. * * Worth calling on a route that swaps models: the WebAssembly heap does * not shrink on garbage collection alone. */ dispose(): Promise; } /** What a loaded predictor is, and how it is configured. */ export declare interface TabularPredictorInfo { /** Graph input name. Not a constant: exporters choose it. */ readonly inputName: string; /** Features per row, or `null` when the graph does not declare it. */ readonly numFeatures: number | null; /** Every graph output, in order. */ readonly outputNames: readonly string[]; /** The output holding predicted classes or regressed values. */ readonly labelOutput: string; /** The output holding class scores, when the graph produces them. */ readonly probabilityOutput: string | null; /** Whether a score output was found. */ readonly isClassifier: boolean; /** Execution providers actually in use. */ readonly providers: readonly string[]; } /** Options for {@link TabularPredictor.create}. */ export declare interface TabularPredictorOptions { /** * Execution providers in preference order. * * Defaults to `["wasm"]`, and that is not a placeholder: scikit-learn * graphs are built from `ai.onnx.ml` operators (`TreeEnsembleClassifier`, * `LinearClassifier`, `Scaler`), which only the WebAssembly backend * implements. */ readonly providers?: readonly string[]; /** * Run one throwaway inference at creation, so the first real prediction * does not pay for allocation and kernel selection. */ readonly warmup?: boolean; /** Session options forwarded verbatim to ONNX Runtime Web. */ readonly sessionOptions?: Record; } /** Lifecycle of the model behind the hook. */ export declare type TabularPredictorStatus = "idle" | "loading" | "ready" | "error"; /** Which reader served the package. */ export declare type TabularRuntime = "onnx" | "compact"; /** * The runtime has no kernels for this graph's operators. * * Measured, and the reason this class exists: importing * `onnxruntime-web/webgpu` loads a WebAssembly build without the * `ai.onnx.ml` domain, so creating a session over any scikit-learn export * fails with `No Op registered for TreeEnsembleClassifier`. The message * names the fix, because the raw error points at the model instead of at * the import. */ export declare class UnsupportedGraphError extends TabularError { constructor(message: string, options?: ErrorOptions); } /** * Load a tabular model and keep it for the component's lifetime. * * @example * ```tsx * function RiskWidget() { * const { predict, isReady } = useTabularPredictor("/models/risk-v3.onnx"); * const [score, setScore] = useState(null); * * async function onSubmit(features: number[]) { * const { probabilities } = await predict([features]); * setScore(probabilities[0]?.[1] ?? null); * } * * return ; * } * ``` * * @param source Model URL, or the bytes when the app already has them. * Pass `null` to hold off loading (a gate, a lazy tab). * @param options Predictor options plus caching. * @returns The predictor, its status, and a `predict` bound to it. */ export declare function useTabularPredictor(source: TabularModelSource | null, options?: UseTabularPredictorOptions): UseTabularPredictorResult; /** Options for {@link useTabularPredictor}. */ export declare interface UseTabularPredictorOptions extends TabularPredictorOptions { /** * Cache the model bytes on the device, so later loads work offline. * * On by default when the source is a URL: an app that runs inference in * the browser almost always wants it to keep working without a network, * and the failure mode of not caching only shows up in a tunnel. */ readonly cache?: boolean | ModelCacheOptions; } /** What {@link useTabularPredictor} returns. */ export declare interface UseTabularPredictorResult { /** The loaded predictor, or `null` while loading or on error. */ readonly predictor: TabularPredictor | null; /** Where the load is. */ readonly status: TabularPredictorStatus; /** Why the load failed. */ readonly error: Error | null; /** Whether the model is loaded and can answer. */ readonly isReady: boolean; /** * Predict for a batch of rows. * * @throws When called before the model is ready — awaiting `isReady` * is the caller's job, and a silent empty result would hide the bug. */ readonly predict: (rows: readonly FeatureRow[]) => Promise; /** Load the model again, e.g. after a failure or a new version. */ readonly reload: () => void; } export { }