0126GitHub
duckdb-jev
Ask a question about every row in SQL, and get a real SQL type back.
colliber/duckdb-jevREADME ↗
# duckdb-jev
Ask a question about every row of a table, in SQL, and get a real SQL type back.
A DuckDB extension over [Jev](https://typesafe.ai), TypeSafe's model for typed
answers instead of text.
## Why
The data you want to ask about already sits in a table or a Parquet file, and SQL is
the query language everyone has. So ask the question where the data is, instead of
pulling it out, wrapping an API in a script and writing the answer back.
Jev picks from a set you define instead of writing an answer you then check. The
result is typed by construction, not by validation, and not generating is what makes
it cheap enough to run on every row.
## Using it
```console
D CREATE SECRET (TYPE jev, API_KEY 'sk-...');
```
`ENDPOINT` and `MODEL` are optional. With no secret, queries fail when planned
rather than part-way through.
Each function takes the row's text, then a **criteria** literal. The criteria is
both the set of permitted answers and the column's type, so it must be constant.
| Call | Criteria | Column |
|---|---|---|
| `jev_choice(text, MAP{option: meaning})` | what each option means | `ENUM` of those options |
| `jev_score(text, [worst, ..., best])` | an ordered rubric | `DOUBLE` on that scale |
| `jev_noul(text, MAP{'true': …, 'false': …})` | what yes and no mean | `DOUBLE`, probability of yes |
| `jev_ask(text, {name: criteria, …})` | any mix | `STRUCT`, one field per question |
The descriptions are the only thing telling the model what an option means.
One request carries many questions, so ask them together. Each field takes its type
from its criteria; choice and score carry a `<name>_confidence` beside them.
```console
D WITH asked AS (
SELECT id, jev_ask(body, {
intent: MAP{'refund': 'wants money back', 'bug': 'something broken'