gpu-ask.js

Agent questions in the browser. Prose in, structured choices out — on-device, nothing sent anywhere.

A ~570k-parameter token tagger (gpu-time lineage) marks the question and options, then a deterministic compiler builds an ask-tool payload your UI can render. Emissions run as ONNX; features, CRF, and compile stay in TypeScript.

Try it

The model is a few megabytes and loads with the page. Pick a real agent turn — highlights mark the question and options; the panel on the right is what a reply UI would show.

Loading model…

Compiled choices appear here.

Response JSON

          

Install

npm install @ai-ecoverse/gpu-ask.js onnxruntime-web

Weights (~10 MB) ship inside the package under models/v13/, and also on Hugging Face. Point loadAsk at either.

import { bundledModelUrl, loadAsk, parse } from "@ai-ecoverse/gpu-ask.js";
import * as ort from "onnxruntime-web/wasm";

const ask = await loadAsk(bundledModelUrl(), { ort });
// or: loadAsk("https://huggingface.co/ai-ecoverse/gpu-ask.js/resolve/main/v13", { ort })
const { questions } = await parse(ask, agentMessage);
// questions[0].kind      → "either_or"
// questions[0].options   → ["merge it now", "wait for CI"]
// questions[0].propose   → true

Schema

One message can yield zero or more questions. Kind comes from the compiler (option count + open/yes-no heuristics). Spans are character offsets in the cleaned text.

Field Type Meaning
kind yes_no | either_or | multi_choice | open How the UI should ask
propose boolean Assistant offers to act (want me to / should I…)
prompt string Question span text
options string[] Tagged choices; empty for yes/no and open
default number | null Index of a recommended option, if tagged
multiSelect boolean Allow several options
span [start, end] Character range of the question

Numbers

Model Params False q Kind options_ok
v12 ensemble (32m distill) 537k × 2 4.0% 83.7% 65.4%
v13 + constrained kind rerank 571k × 2 3.7% 85.4% 67.5%
Ettin-150m teacher (ceiling) 150M 2.4% 87.8% 74.5%

Pooled out-of-fold on 4,930 hand-labeled public agent turns. The browser demo ships the v13 emission ensemble with compiler kind (no Python-only rerank). Target false-question rate is below 5%.

How it works

Sparse hashed features (no vocabulary) feed a bidirectional affine-scan tagger. A linear-chain CRF picks token roles (O, Q_*, OPT_*, REC). Deterministic code turns those roles into questions — recovering missing either/or sides, splitting inline lists, and deciding kind.

For the browser, only the emission network is ONNX (WASM via onnxruntime-web). Tokenization, features, Viterbi, and the compiler run in TypeScript in a Web Worker. ORT loads its SIMD WASM from Vite-bundled wasmPaths (same pattern as kev.js and cua-s1.js). The architecture follows gpu-time; the task is agent ask-tool structure, not time tagging.