Beta. This plugin is early and under active development. The function names, the shape of the answers and the
jevconfiguration scope may all change between releases, and there is no deprecation cycle yet. Pin a version, and expect to revisit pipelines that use it.
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, nothing else:
noul (instructions) // is this true? -> probability
choice (instructions, criteria) // which one? -> winner + distribution
score (instructions, levels) // how much? -> position + distribution
jev (state, questions) // answer them all against one state, in one request
See SPEC.md for the design, and what it deliberately leaves out.
Enable the plugin in your pipeline nextflow.config:
plugins {
id 'nf-jev@0.1.0'
}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}" }
}jev {
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
}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.
Two things to know before turning it on:
- Pin the model. 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. The plugin warns about this; paircacheDirwithmodel = 'jev-1.13.0'. - A cache hit freezes one draw. Repeated live calls on identical input vary a little. Caching makes a run reproducible, not the judgment — a threshold sitting exactly on a boundary will stop flapping for the wrong reason.
Keep cacheDir on a local filesystem; the atomic-publish guarantee is weaker on NFS.
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", not "moderately". On a choice or score, confidence says how concentrated
the distribution is, not whether the answer is right.
Questions sharing a state should be sent together: they are evaluated in parallel and cannot see one another's answers, so a whole rubric costs one request.
Three runnable pipelines under examples/, each against the live API. Every
example has its own README explaining what it asks and what the output means.
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-samplesACCEPT SRR891268 Homo sapiens / ATAC-seq (p=1.0, cell line p=0.95)
ACCEPT SRR031708 Drosophila melanogaster / RNA-seq (p=1.0, cell line p=0.73)
Note SRR891268: its ENA library_strategy is the useless OTHER, and the assay is recovered
from the free-text title alone.
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:
REVIEW R1 clinical=0.01 overclaim=0.48 identifying=0.04 severity=1.37
BLOCK R2 clinical=0.96 overclaim=0.78 identifying=0.08 severity=2.95
BLOCK R3 clinical=0.12 overclaim=0.74 identifying=0.67 severity=2.40
Built from the Nextflow plugin template.
Copy .env.example to .env for local credentials — the Nextflow Registry token used by
make release, and the TYPESAFE_API_KEY the examples need. make sources it into the environment of the
command it runs, and .env is gitignored. The token is read from the environment, so it never
appears in a command line.
make assemble # build
make test # unit tests; no test makes a live API call
make install # install into the local Nextflow plugins dir
make release # publish to the Nextflow RegistryCI builds and runs the unit tests on every push and pull request. It then installs the plugin and
runs all three examples against the live API, asserting how many samples each one decided — never
the probabilities themselves, which move slightly between runs. That job needs a TYPESAFE_API_KEY
repository secret; without one it reports a notice and skips, and it does not run for pull requests
opened from a fork, which have no access to secrets.
Apache License 2.0. See the COPYING file for details.