model2vec 2.0.2 copy "model2vec: ^2.0.2" to clipboard
model2vec: ^2.0.2 copied to clipboard

On-device Model2Vec text embeddings for Dart & Flutter — a self-contained Rust core via FFI and Native Assets. Fast, local, static, minimal memory.

2.0.2 #

Fixes a build hook that could never be cached, so every build of a dependent package paid to rebuild this crate.

  • The hook no longer declares its own build output as its input. It looked for cargo's dep-info beside the artifact as '$binaryPath.d'libm2v_ffi.dylib.d. Cargo writes one dep-info per target, named after the target: a crate built as ["staticlib", "cdylib"] produces libm2v_ffi.a, libm2v_ffi.dylib and a single libm2v_ffi.d. The requested name is written on no platform, so the parse returned nothing every time and the fallback — output.dependencies.add(.directory(nativeDir)) — was not a fallback but the only path ever taken. native/ contains cargo's own target/, so the hook declared as its input a tree it rewrites on every run. Anything that writes there — a second consumer building the same crate — marks the hook dirty, and the runner reports File modified during build. Build must be rerun. and invokes it again. Measured on this repository against hooks 2.1.0, a file written into target/ without touching src/: 1 re-run and 1.55 s before, 0 and 0.85 s after. The re-run is cheap only while cargo itself has nothing to do; when the re-run coincides with a real rebuild the cost is the rebuild, and in a dependent workspace that measured 68 s against 3.5 s settled, with the spawning tests of a parallel dart test timing out. See dart-lang/native#1998 for the same shape reported against native_toolchain_c, and dart.dev/tools/hooks: dependencies are the inputs a hook reads, never the outputs it produces.
  • The dep-info parser no longer breaks on Windows paths. It split the file on the first ':', which on Windows is the drive letter — so C:\out\m2v_ffi.dll: C:\src\lib.rs yielded \out\m2v_ffi.dll as a "dependency": a path that exists nowhere, with the hook still reporting success. That bug was dormant only because the filename above meant the parser was never reached, so fixing the filename alone would have shipped it. The separator is now the first ": ". While there, the parser reads every artifact line rather than only the first, and honours cargo's \ escape so a path containing a space stays one path.
  • When the dep-info really is missing, the fallback now names the crate's actual inputs — native/src/, Cargo.lock, rust-toolchain.toml and the manifest — instead of the directory that holds the build tree.

test/build_hook_test.dart covers both: an integration test reads the dependencies the hook actually writes for the host, and unit tests pin the Windows, multi-line and escaped-space cases that a run on one platform cannot produce. No API change; this is a build-time fix only.

2.0.1 #

Fixes a build hook that broke every Flutter app depending on this package.

  • flutter run no longer fails with "Building native assets failed". The hook read input.config.code without first asking input.config.buildCodeAssets. That is fine for dart build, which only ever invokes hooks with code assets requested — but Flutter also runs them from its asset-bundling pass (buildCodeAssets: null), and with data assets behind a feature flag that pass arrives with build_asset_types empty. Reading .code there throws StateError, the hook exits 255, and Flutter reports the whole app's native-asset build as failed, including the pass that would have built the library. The hook now returns early when no code assets are asked for. test/build_hook_test.dart pins the empty case, which no local dart command reaches on its own.

2.0.0 #

Major release reworking the FFI boundary and public surface for testability and correctness. This release is breaking — see migration below.

Breaking changes:

  • Static API. Model2Vec is now a stateless namespace of static methods. Model2Vec.instance, the Model2Vec(DynamicLibrary) constructor and Model2Vec.boot(...) were removed — the native library is resolved automatically through Native Assets (@Native code assets). Replace Model2Vec.instance.foo(...) with Model2Vec.foo(...).
  • Recommended models. getRecommendedModels() (returning List<Map<String, dynamic>>) is replaced by the typed constant Model2Vec.recommendedModels (List<RecommendedModel>).
  • Typed errors. Model2VecException now carries a Model2VecErrorKind kind; its constructor is (kind, message, [code]) and the fromCode factory is replaced by fromNative(code, message). Native failures surface the message produced by the Rust layer, each with an exhaustively-switchable kind.
  • Lifecycle naming. The initEmbedder* methods are renamed to loadModel*, pairing loadModelunloadModel over the model. initEmbedder, initEmbedderAdvanced, initEmbedderFromBytes and their async forms are removed. Model2VecUtils.similaritySearch /similaritySearchWithThreshold are removed in favour of similaritySearchWithScores (read .index).
  • Batch signature. generateBatchEmbeddings no longer takes batchSize (its signature is now (List<String> texts, {int maxLength})). The native layer batches internally; batchSize remains only on generateEmbeddingStream, which still controls its per-batch size.

Improvements:

  • Native memory safety. The generate_* FFI functions now allocate their output inside the native call (returned as a pointer the caller frees), removing a dimension/model-switch race that could overflow the output buffer. Every native entry point is wrapped in catch_unwind, so a panic (including from a malformed model) surfaces as a typed error instead of undefined behaviour.
  • Windows ABI fix. FFI length parameters use size_t (was unsigned long, 32-bit on 64-bit Windows and mismatched against Rust's usize).
  • Streaming rework. generateEmbeddingStream is rebuilt on small, tested modules — a batching transformer, a transport-agnostic worker protocol, and a worker isolate. Worker errors cross the isolate boundary as typed Model2VecExceptions (kind + code preserved) rather than stringified errors.

New capabilities:

  • Local vector index. EmbeddingIndex — store embeddings by id, then search the nearest by cosine similarity. Optional int8-quantized storage (~4x less memory) and binary toBytes/fromBytes persistence. Turns the package into a local retrieval engine for RAG.
  • RAG pipeline helpers. chunkText (overlapping character chunker), Model2VecUtils.similaritySearchWithScores (index + score), and Model2VecUtils.maximalMarginalRelevance (MMR reranking for diverse results).
  • Lifecycle & DX. Model2Vec.isInitialized (non-throwing check), Model2Vec.unloadModel() (free the native model), Model2Vec.modelInfo (all metadata in one ModelInfo), and Model2VecUtils.dequantizeInt8 (the inverse of quantizeToInt8).
  • Load progress. Model2Vec.loadModelWithProgress() loads on a background isolate and returns a Stream<LoadProgress> reporting the HF weights download (bytesDownloaded / totalBytes / fraction) plus a coarse LoadPhase (resolving → downloading → parsing → done). A cached model or local path streams straight to done.
  • Parallel worker pool. EmbeddingPool fans batches across N worker isolates to embed concurrently across CPU cores.

Migration:

1.x 2.0.0
Model2Vec.instance.generateEmbedding(t) Model2Vec.generateEmbedding(t)
Model2Vec.boot(lib) / Model2Vec(lib) removed — resolution is automatic
Model2Vec.instance.getRecommendedModels() Model2Vec.recommendedModels (typed)
Model2Vec.instance.initEmbedder(path) Model2Vec.loadModel(path)
Model2VecUtils.similaritySearch(q, c) similaritySearchWithScores(q, c).map((r) => r.index)
catch (e) { e.code } still works; add e.kind for exhaustive handling

1.2.0 #

  • Lowered minimum Dart SDK requirement to 3.10.0 to support a wider range of environments.

1.1.0 #

New Features:

  • getRecommendedModels() no longer calls FFI — now returns a hardcoded list of 7 models

  • Removed get_model_list from FFI bindings (Rust, Dart, .h)

  • generateEmbedding() now accepts maxLength parameter — signature changed

  • generateBatchEmbeddings() now accepts maxLength and batchSize parameters — signature changed

  • Streaming APIgenerateEmbeddingStream() for processing large datasets with batching and optional worker isolate

  • Async APIgenerateEmbeddingAsync() and generateBatchEmbeddingsAsync() with maxLength / batchSize support

  • Advanced initinitEmbedderAdvanced() with hfToken, cacheDirectory, normalize, subfolder

  • In-memory initinitEmbedderFromBytes() for loading models from raw bytes

  • boot() — manual initialization with a custom DynamicLibrary

  • isNormalized — getter for L2-normalization check

  • medianTokenLength — getter for median token length

  • maxLength — token truncation parameter for generateEmbedding()

  • batchSize — internal batching control for generateBatchEmbeddings()

  • Model2VecUtils — vector math: cosineSimilarity, dotProduct, euclideanDistance, similaritySearch, similaritySearchWithThreshold, cosineDistance, normalize, meanPooling, quantizeToInt8, toBase64, fromBase64, pairwiseSimilarity

Improvements:

  • Streaming API Performance: generateEmbeddingStream() now utilizes a single long-lived worker isolate instead of spawning one per batch, dramatically reducing IPC and memory overhead for large datasets.
  • Inter-Isolate Communication: Switched from Map<String, dynamic> to Dart 3 Records for significantly faster and strictly typed isolate communication.
  • FFI Optimization: generateEmbedding() in Rust rewritten to avoid array pointer allocations and correctly respect max_length.
  • Refactored quantizeToInt8() to use Dart's native .clamp().
  • Added clear documentation for zero-vector handling in cosineSimilarity and normalize.
  • Added documentation warning about IPC overhead in generateEmbeddingStream for CLI/Server applications.
  • Better error messages when loading the native library fails, explaining possible missing Rust builds.
  • Cleaned up FFI bindings: removed dead get_model_list symbol from .h and bindings.
  • generate_embedding in Rust now returns -5 on empty results instead of silently corrupting data.
  • generate_batch_embeddings_advanced validates result count matches input count.
  • Benchmark updated to run all 5 models.
  • README fully rewritten with API reference and accurate model dimensions.

1.0.0 #

  • Initial version.
2
likes
160
points
257
downloads

Documentation

API reference

Publisher

verified publisherpro100.dev

Weekly Downloads

On-device Model2Vec text embeddings for Dart & Flutter — a self-contained Rust core via FFI and Native Assets. Fast, local, static, minimal memory.

Repository (GitHub)
View/report issues

Topics

#rag #nlp #embeddings #tokenizer #model2vec

License

MIT (license)

Dependencies

code_assets, ffi, hooks, path

More

Packages that depend on model2vec