The instinct is to hand the JSON and the question to an LLM and let it answer. For a tool built to open huge files privately, that's the wrong shape. Here's what QDev does instead — and why.
The model only ever sees the shape of your JSON — the schema we already generate — plus your question. Execution is deterministic jq on the full file.
Aggregations stay exact because jq does the math, not the model: "how much did ben spend in January?" becomes a filter-and-sum that runs on the real values. The model only needed the shape.
jq compiled to WASM is the only query engine. It's purely functional— no mutation, no I/O, no way to reach the network or DOM — so it's safe to run model-generated code. LLMs know jq well, and it covers filter and transform: merge, group, flatten, reshape.
~1–2 MB, lazy-loaded the first time a query runs — it never touches the initial bundle.
strings guard matters — .. also visits objects with no name, and test errors on null. The grounding steers the model to this robust form.Every query — hosted or local — runs through one pipeline. The model has three tools; a bad query comes back to it as a tool result and it retries within a fixed budget.
ask (NL) └─▶ grounding: relevance-sliced schema + samplePaths (value-free) └─▶ agent loop (bounded turns) ├─ inspect(path) — narrow the schema slice ├─ run_jq(expr) — error/empty loops back └─ final(expr) — commit → result
The model gets exactly two things: your schema and your question. That's it — no values, no sampled rows, redacted or otherwise. If a query comes back empty because a value's format was ambiguous — an ISO date vs an epoch, active vs ACTIVE — you refine the question or edit the jq; the data stays in your tab. Hosted uploads a schema and a sentence; local WebLLM uploads nothing. The proxy is stateless and logs neither prompts nor results.
The app depends only on a LanguageModel interface. Local AI is free — the gateway; hosted (QDev Pro) is the paid tier.
Small structured input to the model, deterministic jq on your machine. Go try it.