jev processor
Makes typed, calibrated decisions about each message using TypeSafe's System One (jev) API.
- Common
- Advanced
# Common config fields, showing default values
pipeline:
processors:
- label: ""
jev:
api_key: "" # No default (required)
model: "jev-latest"
state: "" # No default (optional)
questions: [] # No default (required)
target: "body"
result_key: "jev"
include_probabilities: true
min_confidence: 0
abstain_value: "uncertain"
on_error: "fail"
timeout: "30s"
max_retries: 3
# All config fields, showing default values
pipeline:
processors:
- label: ""
jev:
api_key: "" # No default (required)
base_url: "https://api.typesafe.ai/v1/systemone"
model: "jev-latest"
state: "" # No default (optional)
questions: [] # No default (required)
target: "body"
result_key: "jev"
include_probabilities: true
min_confidence: 0
abstain_value: "uncertain"
on_error: "fail"
timeout: "30s"
max_retries: 3
Sends each message to the TypeSafe System One decision API and writes the typed answers back onto the message. Instead of free-text generation, System One answers a fixed set of typed questions with calibrated confidence, so pipelines can classify, extract, screen, score, and route deterministically.
Each question is one of three types, all answered in a single request:
choice: pick one option fromchoice_criteria. Returns the choice, its confidence, and per-option probabilities.score: rate againstscore_criteria(low to high). Returns a weighted score, confidence, and per-level probabilities.noul: judge whether an instruction/statement is true. Returns a probability in [0,1].
Answers are written to message metadata (for routing with a downstream switch), the JSON body (to enrich records), or both, under result_key. Metadata keys are flattened as <result_key>_<name> and <result_key>_<name>_confidence so a downstream switch can branch on the decision and its confidence.
Consuming the results: read the body decision in a downstream mapping (e.g. this.jev.<name>.choice), or route on the metadata with a switch output that checks @jev_<name> and @jev_<name>_confidence. See the jev-classify-and-route example pipeline for both.
Confidence gating (optional) turns calibrated confidence into a decision so consumers do not repeat it: set min_confidence and a low-confidence choice becomes abstain_value (default "uncertain") while choice/score answers gain a confident boolean; set a question's true_above to get a boolean noul. A downstream switch can then route on @jev_<name> with no confidence arithmetic.
This processor calls a remote, third-party API: the node must have outbound connectivity to the endpoint, and message content leaves the node. Use it on connected fleets, not air-gapped ones. Because a secret refresh restarts the job, pipelines using this processor should set restart_policy: always.
Examples
Classify and enrich
Add a routing decision and an urgency flag to each JSON record's body.
pipeline:
processors:
- jev:
api_key: ${TYPESAFE_API_KEY}
state: ${! json("message") }
questions:
- name: department
type: choice
instructions: Which team should handle this
choice_criteria:
billing: Payment or subscription issues
technical: Bugs or integration problems
sales: Pricing or account questions
- name: is_urgent
type: noul
instructions: The message conveys urgency or time-sensitivity
target: body
Confidence-gated routing
Classify to metadata, then route only high-confidence hits with a switch.
pipeline:
processors:
- jev:
api_key: ${TYPESAFE_API_KEY}
questions:
- name: intent
type: choice
instructions: Classify the request intent
choice_criteria:
refund: Wants money back
support: Needs technical help
other: Anything else
target: meta
output:
switch:
cases:
- check: '@jev_intent == "refund" && @jev_intent_confidence.number() > 0.8'
output: { label: refunds, drop: {} }
- output: { label: review, drop: {} }
PII guardrail
Drop messages that likely contain personal data before they leave the node.
pipeline:
processors:
- jev:
api_key: ${TYPESAFE_API_KEY}
questions:
- name: has_pii
type: noul
instructions: The text contains personally identifiable information
target: meta
- mapping: root = if @jev_has_pii.number() > 0.5 { deleted() }
Fields
api_key
API key for the decision service, sent as a bearer token. Supports environment/secret interpolation, e.g. ${TYPESAFE_API_KEY}.
This field contains sensitive information. Use a secret reference rather than a literal value.
Type: string
base_url
The decision API endpoint. Override only to target a compatible proxy.
Type: string
Default: "https://api.typesafe.ai/v1/systemone"
model
Model to evaluate against. Pin a version (e.g. jev-1.13.0) for reproducibility.
Type: string
Default: "jev-latest"
state
The input state to evaluate, templated from the message, e.g. ${! json("text") }. When omitted, the whole message is sent (as a JSON object when the body is JSON, otherwise as raw text).
This field supports interpolation functions.
Type: string
questions
The typed questions to answer for each message. At least one is required.
Type: array of object
questions[].name
Question key. Also the key the answer is written under.
Type: string
questions[].type
Question type: choice, score, or noul.
Type: string
Options: choice, score, noul
questions[].instructions
What to decide, in plain language (e.g. "Which team should handle this").
Type: string
questions[].choice_criteria
For type=choice: option -> description. At most 255 options.
Type: map of string
questions[].score_criteria
For type=score: ordered rubric levels, lowest to highest (at least two).
Type: array of string
questions[].min_confidence
For type=choice/score: overrides the top-level min_confidence for this question, in [0,1].
Type: float
questions[].true_above
For type=noul: emit a boolean (noul >= true_above) instead of the raw probability, in [0,1].
Type: float
target
Where to write answers: "body" splices them into the JSON body under result_key; "meta" writes flat metadata keys for routing; "both" does both.
Type: string
Default: "body"
Options: meta, body, both
result_key
Body object key and metadata-key prefix the answers are written under.
Type: string
Default: "jev"
include_probabilities
Include the full probability distribution (and score legend) in the body answers. Metadata always carries only the scalar value, confidence, and confident flag.
Type: bool
Default: true
min_confidence
Confidence gate for choice/score answers, in [0,1]. When a choice answer's confidence is below this its value becomes abstain_value (so a downstream switch can route the uncertain case explicitly), and choice/score answers gain a confident boolean. 0 disables gating; a per-question min_confidence overrides this.
Type: float
Default: 0
abstain_value
The choice value emitted when confidence is below min_confidence. Must not match a choice option.
Type: string
Default: "uncertain"
on_error
What to do when the API errors or is unreachable after retries: "fail" returns the error so the message is marked failed (default); "passthrough" emits the message unchanged with a <result_key>_error metadata key; "drop" discards the message.
Type: string
Default: "fail"
Options: fail, passthrough, drop
timeout
Per-request timeout for the API call.
Type: string
Default: "30s"
max_retries
Retry attempts for transient failures (timeouts, 5xx, 429, 529), with exponential backoff.
Type: int
Default: 3