Jev (TypeSafe AI) inside SQL and document pipelines: pg-jev, sqlite-jev, DocJev
What pg-jev, sqlite-jev, sqlite3-jev, pg-redact and DocJev do when a Jev call fails, is unsure or has no key, and what text they send. 8 Oct 2026. The title is the pool's own label. When the pool checked search suggestions on , no phrase about Jev in databases was offered by two of the three endpoints: Google offered "jev postgres", Bing and DuckDuckGo offered nothing for it, and "jev sql", "jev sqlite", "jev database" and "jev pdf" had no matching suggestion on any of the three. A suggestion shows that people search for something; it does not show how many.
On a Jev error, all 5 stop the query or request; pg-redact also stores text unredacted when a span's answer is missing or below 0.5. All 5 send row or document text out.
Every project the pool found that calls Jev from inside a SQL statement or a document pipeline and that was read at a pinned commit (5 on 8 Oct 2026); not a survey. Six further SQL candidates are listed but not audited (below). The pool installed and ran none of them and made no Jev call.
Before you call Jev from a query or a pipeline
- Expect a Jev error to stop the statement or the request.fail-closed 5 of 5
All 5 raise on a Jev error or timeout (5 of 5
fail-closed). In SQL that aborts the statement; it does not return partial rows. Timeouts and retries per project are in the table; general advice is on errors and rate limits. - Know what "unsure" becomes.returns to the query 2no-threshold 1acts-anyway 2
Below threshold, 2 of 5 return false or 0 to your query (pg-jev, sqlite-jev, threshold 0.5), 1 of 5 has no threshold and returns the raw value (sqlite3-jev), and 2 of 5 act anyway (pg-redact stores the span unredacted; DocJev joins the page to the current document).
- Do not use a Jev predicate as an access-controlpg-jev, sqlite-jev: answer cache
WHEREclause.Below the threshold
jev()returns false; answers are cached per session (pg-jev) or per process (sqlite-jev), so a changed policy may not be asked again. - Assume the whole row or page leaves the database.5 of 5 send text out
pg-jev sends each whole row as JSON, not only the columns in the predicate. See what each project sends.
- Set a spend guard.calls per row in the table
pg-jev sends one request per 20 rows; sqlite-jev's
jev_rowstable sends up to 500 rows per query in batches of 40.
What each project does when Jev fails, is unsure or has no key
Documented Source at the pins below. Error, malformed and no-key cells and timeouts were read on 7 Oct 2026 and reused; what Jev decides, below threshold, bypass, data sent and calls were read on 8 Oct 2026, 05:15–05:16 UTC, at the same pins. Colour marks the verdict cells only (error, malformed, below threshold, no key).
- fail-closed or held (the item does not go ahead; a person, the host's prompt or, for two passage filters, the code's own cut decides)
- fail-open or acts-anyway; a "conditional" cell that can act is counted fail-open
- fallback-<what> (named in the cell)
- no-decision (nothing returned; caller must handle)
- advisory (Jev never decides), or conditional where the page has no count
- not recorded, not applicable or no-threshold (the cell says which)
| Project (commit) | What Jev decides | Jev error or timeout | Malformed answer | Below threshold | No key | Bypass | What leaves the database | Calls | Counted on When Jev fails? |
|---|---|---|---|---|---|---|---|---|---|
realZachi/pg-jev (8d9598d)PostgreSQL extension (PL/Python) | Noul, score or choice per row; jev() returns a boolean | fail-closedConnection errors and 408, 429, 529 and 5xx retried up to 7 attempts, then the statement errors; other HTTP errors raise at once. Timeout jev.timeout 30 s per connection; statement_timeout and cancel still work | fail-closedMissing answers in a batch raise an error. A non-JSON body raises an uncaught ValueError, not retried; what PostgreSQL returns then was not read | not applicable: returns false to the queryprob >= coalesce(arg, jev.threshold, 0.5) | fail-closedfor a typesafe.ai host ("jev: no API key"); another host gets the request without Authorization | Recorded: answer cache per backend session, keyed on row hash and question | The whole row as JSON (to_json), every column | One request per batch of 20 rows | No: returns to the query |
mattn/sqlite3-jev (2172600)SQLite C extension (libcurl) | Noul (REAL 0..1), choice or score per call | fail-closedA curl error or timeout returns an SQL error, no retry; 429 and 529 retried 3 times, then an error. Timeout 60 s by default, can be changed | fail-closed"jev: unexpected response" when the body cannot be parsed. A JSON body without the expected path would give SQL NULL through json_extract: engine behaviour, not read, not counted | no-thresholdReturns the REAL or TEXT value to the query | conditional: sent without a keyNo early error; the request goes out without Authorization ("no key means an open server"); a non-2xx answer is then fail-closed | None found (no cache) | Whatever state argument the SQL passes | One HTTP call per function call | No: returns to the query |
mgaitan/sqlite-jev (1ac946c)SQLite extension with a jev_rows virtual table | Noul, choice or score per row | fail-closed"jev: TypeSafe request failed", no retry on transport errors; 429, 529 and 5xx get 4 attempts, then an error. Timeout 90 s, can be changed | fail-closedInvalid JSON, a missing answer, a malformed noul or a missing batch answer raise an error. In jev_rows, an answer that lacks a field gives a NULL column (no-decision) | not applicable: returns 0 (false) to the queryjev() threshold 0.5 | fail-closed"jev: no API key; export TYPESAFE_API_KEY" | Recorded: answer cache | The state argument; jev_rows sends every non-hidden column | One per call, or batches of 40 rows in jev_rows; max_rows 500 | No: returns to the query |
rishi-raj-jain/pg-redact (ee903ef)Next.js demo app that redacts personal data, then writes to Postgres | Choice per candidate span: PII type or "none" | fail-closed502, no insert. No timeout set on fetch (the route's maxDuration = 300 is a platform limit) | fail-openA missing span answer: the span is skipped and the message is stored with it unredacted; a broken body gives 502 | acts-anywayA span below 0.5 is stored unredacted (CONF_THRESHOLD = 0.5) | fail-closed"TYPESAFE_API_KEY is not set", 502 | Recorded: a message with no candidate spans is stored without a Jev call; the IP rate limit rejects before the call | The whole pasted message, sent before it is stored | One request per message | Yes: its code decides which spans are redacted before the write |
jerryjliu/docjev (c7abe27)Document pipeline: classify and split | Category choice per document; per page, a category choice and a boundary noul | fail-closed2 attempts, then ProviderError; SDK retries set to 0. A context-size rejection halves the page window in split. Timeout 30 (unit set by the SDK, not stated) | fail-closed"Jev returned an incomplete answer set."; an invalid category or page decision also raises | acts-anywayA page below 0.5 joins the current document (boundary_threshold = 0.5). Category choice: no threshold recorded | fail-closedProviderError("Set TYPESAFE_API_KEY to use Jev...") when the engine is built | Recorded: blank pages are set to "other" without a call; an all-blank document raises before any call | Page text | One per document (classify) or per page window (split) | Yes: its code builds the page groups from Jev's answers |
- Jev error or timeoutof 5
- fail-closed5 of 5
- Malformed answerof 5
- fail-closed4 (pg-jev, sqlite3-jev, sqlite-jev, DocJev)
- fail-open1 (pg-redact)
- Below thresholdof 5
- returns false or 0 to the query2 (pg-jev, sqlite-jev)
- no-threshold1 (sqlite3-jev)
- acts-anyway2 (pg-redact, DocJev)
- No keyof 5
- fail-closed4
- sent without a key1 (sqlite3-jev)
- Bypassof 5
- recorded4
- none found1 (sqlite3-jev)
sqlite-jev's malformed cell is counted fail-closed; its jev_rows NULL-column path is a no-decision detail inside that cell. pg-redact's malformed cell is counted fail-open because a missing span answer stores text unredacted; a broken body gives 502.
Which of the 5 are counted on When Jev fails
Counted 2 of 5; returns to the query 3 of 5.
- Not counted (3): pg-jev, sqlite3-jev and sqlite-jev. These three SQL extensions return Jev's value into your query. Your query, not the extension, decides what to do with that value, so they are listed but not counted on When Jev fails. This follows the pool's counting rule from 8 Oct 2026. A Jev error still aborts the statement, as the table above shows.
- Counted (2): pg-redact and DocJev. Their own code acts on Jev's answer: pg-redact decides which spans are redacted before it writes the message; DocJev builds the page groups. Two rows are too few for a domain of their own, so they sit in the nearest existing domains on When Jev fails by domain: pg-redact under Content moderation (PII redaction before storage) and DocJev under Email and lead (document splitting).
Engine behaviour that was not read
Two outcomes depend on the database engine, not on the extension's code. The pool did not read them and does not count them as cells.
- PostgreSQL after pg-jev's uncaught
ValueError. A non-JSON 200 body raisesValueErroratjson.loads; pg-jev'sanswer()catches onlyRuntimeError, so the error escapes. What PostgreSQL then returns to the client was not read. - SQLite
json_extracton a missing path in sqlite3-jev. A JSON body without the expected path would give SQL NULL instead of an error. This path was not read or tested.
What text leaves the database
Documented From source at the pins above, read 8 Oct 2026.
pg-jev sends each whole row as JSON (every column), 20 rows per request. The SQLite extensions send what the SQL passes; sqlite-jev's jev_rows sends every non-hidden column. pg-redact sends the whole message before it stores it. DocJev sends page text. How long that text is kept depends on the route you call Jev through: see What data leaves your system when you use Jev. Timeouts and retries in general: Jev errors and rate limits.
No project publishes a price or token count per row, so this page gives no cost per row; calls per row or batch are in the table.
Six further SQL candidates (not audited, not counted)
Found on 8 Oct 2026 and read for one line each at the commit shown (HEAD on 8 Oct, 05:16 UTC). Documented for the line quoted; nothing else was read.
- judoaseeta/duckdb-jev (
58e5484): calls api.typesafe.ai; its booleannumber >= thresholdreturns to the query. - Sheltercosmo/jev4pg (
511432a): aTYPESAFE_API_KEYread was found; the call path was not recorded. - wuxianliang/pg_typesafe (
11d9358): reads the key fromTYPESAFE_API_KEY; the endpoint was not located. - sashimikun/sql-jev (
f8a6937):fetch(config.apiUrl); default URL not read; predicates return to the query. - Peterrallojay/sqlite-utils-jev (
8ddfaeb): calls the TypeSafe endpoint and raises with no key. Its README says it saves results (Reported); the write was not located. - qsliu2017/pg_jevplanner (
5e88834): a PostgreSQLplanner_hookthat falls back tostandard_planner. Its own code acts on Jev's answer (query planning), so it could be counted on When Jev fails after a full read.
What was not verified
- What PostgreSQL returns after pg-jev's uncaught
ValueError(engine behaviour). - The SQLite
json_extractNULL path in sqlite3-jev (engine behaviour). - pg-redact's timeout: none is set in its code; only a platform limit applies.
- DocJev's timeout unit (set by the SDK) and its OCR path. The README says unreadable OCR fails and optional cloud OCR changes where data goes (Reported, not rechecked).
- Cache lifetimes: pg-jev's is per session according to its own code comment; sqlite-jev's was not read.
- The six further candidates beyond one line each.
- No project was installed or run, no query was run and no Jev call was made. Whether anyone uses these projects in production was not checked.
Sources and check times (UTC)
Sources (R11 and R10 IDs, pinned commits, paths)
- R11-S11: search suggestions from Google (
client=firefox), Bing (osjson) and DuckDuckGo (ac), 8 Oct 2026, 05:16:53–05:17:21. "jev postgres" completed by Google only, from "jev post" and "jev postg"; "pg-jev" returned by Google among unrelated completions. - R11-S217 (8 Oct, 05:15:30) and R10-S301 to R10-S313 (7 Oct reads, same pins): pg-jev at 8d9598d,
sql/jev--0.2.1.sqlL10–17, L23–24, L90–100, L93–94, L97, L111–124, L210, L222, L238–242, L293, L381–386, L426–429, L439–446, L497–499, L503. - R11-S218 (05:15:40): sqlite3-jev at 2172600,
jev.cL4–16, L36–37, L229–234, L274–278, L391. - R11-S219 (05:15:50): sqlite-jev at 1ac946c,
src/jev.cL25–27, L373–375, L430, L517–522, L528–533, L540, L584–597, L604, L614, L879, L982–983, L1063–1065, L1241–1246. - R11-S220, R11-S221 (05:16:00): pg-redact at ee903ef,
src/lib/jev.tsL5, L34–46, L55, L64–75;src/app/api/classify/route.tsL29–58. PyPIpg-redact: 404 (no package). - R11-S222 (05:16:10): docjev at c7abe27,
src/jev_docs/engines/jev.pyL118–119, L124–166, L209–210, L224, L231–238, L240–257, L260–276, L285. - R11-S223 to R11-S228 (05:16:40): the six candidates at the commits linked above; duckdb-jev
src/jev_config.cppL21,jev_functions.cppL257; jev4pgdeploy/configure.pyL26; pg_typesafetypesafe.cL322; sql-jevsrc/api.tsL107; sqlite-utils-jevclient.pyL19, L352; pg_jevplannersrc/pg_jevplanner.cL129–131, L151, L199–201. - Research notes:
runs/2026/10/61ac0fbc-a501-4f48-b1e5-503fd921a06e/research/databases-and-documents.mdandwhen-jev-fails-recount.md; source listsources.jsonlin the same directory.