createDecider method
- @experimental
- @nonVirtual
- required List<
DeciderOption> options, - DeciderMethod method = DeciderMethod.centroid,
- EmbeddingDeciderCalibration calibration = const EmbeddingDeciderCalibration.crossFit(),
- String? embedderId,
- CancelToken? cancelToken,
- void onProgress()?,
A decider that picks one of options for an input, or abstains.
Every option's inputs — its description, then its examples — are
embedded once, here, with TaskType.sentenceSimilarity (the prefix every
compared input gets), and fitted by method: centroids, plus the linear
layer for DeciderMethod.linear. calibration sets when the decider
abstains; the default cross-fit needs two inputs per option. A
choose then costs one embed and a dot product per option.
The decider borrows this model and never closes it. When a model
FlutterEdgeAi.getActiveEmbedder returned is closed — core replaced it
(other media, another backend, a re-install), its worker died, or the
app closed it — the decider's next choose asks core for the active
embedder again, with the backend and media this model was built with
(so it may load the model again), and retries there when that
embedder's space id is the decider's; another space fails with
DeciderSpaceMismatchException. On any other model choose fails with
EmbedderClosedException and the decider reports isClosed: reload it
with loadDecider from its toArtifact() — no re-embedding.
embedderId names the model's weights in the decider's embedding-space
id. A model FlutterEdgeAi.getActiveEmbedder returned is named by its
installed files unless one is given: their names and, natively, their
sizes in bytes — file names and sizes, not the bytes themselves (on web
the names alone). Any other model (a test fake, a custom subclass)
needs an embedderId, and so does a model whose activeBackend is
null (LiteRT.js and ONNX on web): without a backend to tell WebGPU from
WASM, the call is refused with ArgumentError. An embedderId
REPLACES the installed-file guard: the caller owns the identity, and
with a null activeBackend it must name the backend too. The space id
also holds the dimension, activeBackend and the task prefix, so a
decider fitted on the CPU file is never loaded onto an NPU bundle's
vectors, and — when an option example or a labelled request is an
image — the engine's image budget (EmbeddingGemma 2: 140 or 70 tokens
per image), so image vectors of one budget never meet the other's.
cancelToken stops the embedding of the options and the fit (natively
the fit's isolate is killed; on web the fit stops at its next yield);
the call then fails with DeciderCancelledException and returns no
decider.
onProgress counts the inputs this call embeds — each option's
description and examples, then the rows of
EmbeddingDeciderCalibration.fromLabelled — as (done, total):
(0, total) first, then once per input as its vector comes back, ending
at (total, total). It does not cover the fit that follows: a
DeciderMethod.linear fit at 150 options takes seconds after the last
call. A throw from it fails the call.
Errors arrive as a FAILED FUTURE: ArgumentError for options it cannot
use (none, duplicate ids, an option with nothing to embed, a calibration
these options or labelled rows cannot support) and for
DeciderMethod.optionScoring, an InferenceModel method; StateError
for a vector that is not finite or not dimension long and for a fit
that is not finite (an option whose inputs cancel out); and this model's
own failures — an over-long input is EmbeddingInputTooLongException,
never truncated; an input's failure names its option and input, with its
type and fields kept.
Experimental: may change in a minor release while the API settles.
Implementation
@experimental
@nonVirtual
Future<Decider> createDecider({
required List<DeciderOption> options,
DeciderMethod method = DeciderMethod.centroid,
EmbeddingDeciderCalibration calibration =
const EmbeddingDeciderCalibration.crossFit(),
String? embedderId,
CancelToken? cancelToken,
void Function(int done, int total)? onProgress,
}) => createEmbeddingDecider(
this,
options: options,
method: method,
calibration: calibration,
embedderId: embedderId,
cancelToken: cancelToken,
onProgress: onProgress,
);