flutter_gemma_rag_sqlite 1.1.0
flutter_gemma_rag_sqlite: ^1.1.0 copied to clipboard
SQLite vector search (sqlite-vec) on-device RAG vector store for flutter_gemma. Opt-in package; implements flutter_gemma's VectorStoreRepository.
flutter_gemma_rag_sqlite #
First-class SQLite vector store for flutter_gemma.
KNN runs inside SQLite via sqlite-vec
(vec0 virtual table) — no Dart brute-force, no in-memory index.
Opt-in package implementing VectorStoreRepository:
- Native (Android/iOS/macOS/Linux/Windows):
SqliteVectorStore—package:sqlite3(dart:ffi) + the per-platformvec0loadable extension. - Web:
WebSqliteVectorStore—package:sqlite3/wasm.dartdriving a customsqlite3.wasmwithsqlite-vec/vec0statically linked.
Both arms speak the same vec0 SQL dialect, so KNN and Filter behave
identically across all six platforms. A vec0 table declares an id TEXT PRIMARY KEY, so KNN returns the document id directly — no JOIN, no rowid bridge.
Usage #
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter_gemma/flutter_gemma.dart';
import 'package:flutter_gemma_rag_sqlite/flutter_gemma_rag_sqlite.dart';
await FlutterGemma.initialize(
vectorStore: kIsWeb ? WebSqliteVectorStore() : SqliteVectorStore(),
);
searchSimilar returns cosine similarity (1 = identical, higher = better),
sorted descending, filtered by threshold — the same contract as the qdrant
store (vec0 returns distance; the store converts 1 - distance at the boundary).
Declared-column filters #
vec0 filters KNN only on declared, typed metadata columns (not arbitrary
JSON). Declare the filterable fields once at init via filterSchema:; the store
promotes those fields out of each document's metadata JSON into real columns and
translates Filter (must/should/mustNot) into a vec0 WHERE:
await FlutterGemma.initialize(
vectorStore: kIsWeb ? WebSqliteVectorStore() : SqliteVectorStore(),
filterSchema: const FilterSchema(fields: [
FilterField(name: 'lang', type: FilterFieldType.string),
FilterField(name: 'year', type: FilterFieldType.number),
FilterField(name: 'archived', type: FilterFieldType.bool),
]),
);
// later, at query time:
final hits = await store.searchSimilar(
queryEmbedding: queryVec,
topK: 10,
filter: const Filter(
must: [FieldRange(key: 'year', gte: 2000)],
mustNot: [FieldEquals(key: 'archived', value: true)],
),
);
Filtering on an undeclared key is a safe no-op (never throws). With no
filterSchema, the store ignores filters entirely — identical to filter: null.
Supported operators: =, !=, >, >=, <, <=, BETWEEN, IN
(FieldEquals, FieldRange, FieldMatchAny); max 16 declared columns.
Setup #
Native needs no setup — the vec0 loadable extension is fetched per platform
by this package's Native Assets hook (hook/build.dart), SHA256-verified, and
loaded automatically before any database is opened.
Web ships the custom sqlite3.wasm (with sqlite-vec linked in) as the
package web asset web/rag/sqlite3.wasm. Copy it into your app's web root so it
sits next to index.html at rag/sqlite3.wasm — that's the URL
WasmSqlite3.loadFromUrl fetches. Resolve the package directory with
dart pub deps/flutter pub (the path printed by your IDE) and copy the asset:
mkdir -p web/rag
# <pkg> = the flutter_gemma_rag_sqlite directory in your pub cache / workspace
cp <pkg>/web/rag/sqlite3.wasm web/rag/sqlite3.wasm
OPFS persistence and SharedArrayBuffer require your web server to send the
cross-origin isolation headers:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
There is no CDN <script>, no wa-sqlite worker, and no index.html wiring
anymore.