nf-jev @ 0.2.1
Summary
nf-jev exposes TypeSafe System One judgments as ordinary Nextflow functions. A pipeline builds typed questions as values, asks them, and gates on the returned probabilities with plain Nextflow operators.
Jev is not a language model. It generates no text, holds no conversation and calls no tools: it answers typed questions about the state you give it, and returns a probability distribution over the answers you allowed. That makes it something a pipeline can branch on — unlike a number a language model reports about its own confidence, which it invented.
Four functions are provided:
noul (instructions [, criteria])— is this true? → probabilitychoice (instructions, criteria)— which one? → winner + distributionscore (instructions, levels)— how much? → position + distributionjev (state, questions)— answer them all against one state, in one request
Get Started
Enable the plugin in your pipeline nextflow.config:
plugins {
id 'nf-jev@0.2.1'
}
Set your credential — either jev.apiKey in the configuration, or the TYPESAFE_API_KEY environment variable:
export TYPESAFE_API_KEY="..."
Then ask a question:
include { jev; noul } from 'plugin/nf-jev'
workflow {
channel.of('The assembly meets the stated QC bar.')
.map { text -> jev(text, [clinical: noul('The text gives clinical guidance.')]) }
.view { answers -> "clinical: ${answers.clinical.noul}" }
}
Configuration
jev {
provider = 'typesafe' // or 'openrouter', see below
apiKey = secrets.TYPESAFE_API_KEY // or $TYPESAFE_API_KEY
model = 'jev-latest' // pin a snapshot to fix a result
endpoint = 'https://api.typesafe.ai/v1/systemone'
timeout = 30 // seconds, per request
cacheDir = "$projectDir/.jev-cache" // unset = no caching
}
Everything but the key has a default. provider picks the defaults for endpoint and model and names the environment variable the key falls back to; it is inferred from the host of endpoint when left out, so an openrouter.ai endpoint alone is enough to select OpenRouter.
OpenRouter
Jev is also served by the OpenRouter Decisions API. Select it with one setting:
jev {
provider = 'openrouter' // endpoint https://openrouter.ai/api/alpha/decisions
apiKey = env('OPENROUTER_API_KEY') // the default fallback; or secrets.OPENROUTER_API_KEY
model = 'typesafe/jev-1.13' // the default; OpenRouter ids are namespaced
}
Only OPENROUTER_API_KEY is read for OpenRouter and only TYPESAFE_API_KEY for TypeSafe. A noul can spell out what a yes and a no mean with the two-argument form, on either provider:
noul('Has this run been seen before?',
[true: 'The title or accession mentions a prior submission', false: 'Nothing points to one'])
Caching
Set jev.cacheDir and responses are cached, keyed on a SHA-256 of the exact request — model, state and questions. Unset it and nothing is cached. Entries are published atomically, so concurrent runs can share a directory; an entry that will not parse is treated as a miss and the question re-asked, so a truncated file can never poison a pipeline. There is no eviction: rm -rf the directory.
Important: Pin the model when using caching. With the default model = 'jev-latest' the key holds a floating alias, so cached answers keep being replayed after the alias moves to a newer snapshot. Pair cacheDir with model = 'jev-1.13.0' on TypeSafe, or a dated id such as model = 'typesafe/jev-1.13-20260917' on OpenRouter.
Reading an answer
answers.is_human // [type: 'noul', noul: 0.98]
answers.assay // [type: 'choice', choice: 'RNA-seq', confidence: 0.99, probabilities: [...]]
answers.tissue // [type: 'score', score: 1.97, confidence: 0.96, legend: [...], probabilities: [...]]
A noul has no separate confidence — the probability is the answer, and 0.5 means "equally likely either way". On a choice or score, confidence says how concentrated the distribution is, not whether the answer is right.
Examples
Three runnable pipelines are provided under the examples/ directory, each against the live API.
label-samples — fetch ENA run metadata with an ordinary process, label each run against a controlled vocabulary, and split the cohort on a calibrated confidence:
nextflow run examples/label-samples
route — pick a QC depth per sample and dispatch to different processes. No agent and no generated text; a low-confidence pick falls through to the more thorough branch, which is one readable line rather than a hope expressed in a prompt.
guardrail — screen generated text with a hazard rubric (three nouls and a severity score) in a single request, with the block/review/pass thresholds in nextflow.config:
workflow {
// Screen text with hazard rubric
channel.of(text1, text2, text3)
.map { text ->
jev(text, [
clinical: noul('Does this give clinical guidance?'),
overclaim: noul('Does this overclaim efficacy?'),
identifying: noul('Could this identify someone?'),
severity: score('How severe is the combined hazard?', ['low', 'medium', 'high'])
])
}
.view { answers ->
"clinical=${answers.clinical.noul} overclaim=${answers.overclaim.noul} severity=${answers.severity.score}"
}
}
License
Apache License 2.0. See the COPYING file for details.
| Nextflow version | >=25.10.0 |
|---|---|
| Depends On | - |
| Release Date | 12 Oct 2026 14:09:28 (UTC) |
| Release Notes | - |
| Download URL | https://registry.nextflow.io/api/v1/plugins/nf-jev/0.2.1/download/nf-jev-0.2.1.zip |
| Store URL | https://public.cr.seqera.io/v2/nextflow/plugin/nf-jev/blobs/sha256:403cfd6f0133b3173bdad3a0dfb4cef5784dc10908393fe1211e0530cf2a34ee |
| Size | 22.8 KB |
| Checksum | a7788cf3cc1234ee4a8cec148d0f13133fcc0912dc1c10fd6466e05fab7367cd9e8a14d563a91714663249b305220bcd30551b96fad99d0af711793104306f58 |
| Total downloads | 157 View trends |
| Security Scan |