ONNX export of the classification path of fastino/GLiNER2.5-Decide, packaged for Transformers.js and the open-jev typed-decision library. It runs on WebGPU (WASM fallback) with nothing leaving the tab.
GLiNER2.5-Decide is a DeBERTa-v3-large encoder with a trained label head, made by Fastino for typed operational decisions: routing, sentiment, yes/no gates, ordinal scores. Its extraction heads (span, boundary, record) are not part of this export.
import { OpenJev, choice, noul, score } from "open-jev";
const jev = await OpenJev.load({ model: "gliner2-decide" }); // or "onnx-community/GLiNER2.5-Decide-ONNX"
const [team, angry, severity] = await jev.decide(
"The export button crashes in Safari but works in Chrome. Not blocking.",
[
choice("Which team should handle this?", ["billing", "technical support", "sales"], {
billing: "charges, refunds, invoices",
"technical support": "bugs, outages",
}),
noul("Is the customer angry?"),
score("How severe is this bug?", ["cosmetic", "degraded but there is a workaround", "blocking"]),
],
);
Inputs: input_ids[batch, sequence], attention_mask[batch, sequence], marker_positions[batch, markers] (int64, index of every [L] token). Output: logits[batch, markers], one logit per label from the model's 1024→2048→1 head. Softmax within each question's markers gives the distribution.
The sequence is the GLiNER2 processor's classification layout, which the caller must reproduce exactly (open-jev does):
The prompt is the task text, with per-label descriptions appended as [DESCRIPTION] label: description.
The prompt and the labels keep their case and are tokenized as whole strings.
The state is lowercased, split with the processor's word regex, given a terminal . if it has none, and tokenized one word at a time with no special tokens.
( and ) are tokenized as standalone words. No [CLS]/[SEP].