Filters and expressions
TypeScript JQL filter and expression constructors with exact validation rules.
judgeval-js JQL source on GitHub
Public filter constructors
status(value)
name(value)
model(value)
cost(bounds)
duration(bounds)
judge(judgeName, value?)
judged(options)
attr(key, value?, selector?)
grep(field, value)
rg(field, pattern, { ignoreCase? }?)
tokens(field, words)
eq(field, value) / ne(...) / gt(...) / gte(...) / lt(...) / lte(...)
citedBy(judgeName, value?)
all(first, ...rest) / any(first, ...rest) / not(filter)
anySpan(filter) / everySpan(filter) / noSpan(filter)
anyTrace(filter) / everyTrace(filter) / noTrace(filter)
descendantOf(filter, depth?) / ancestorOf(filter, depth?)
overSpans(agg, cmp, value, where?)
overTraces(agg, cmp, value, where?)
overScores(agg, cmp, value)
atLeast(k, of, where?)Leaf filters
| Operation | Required inputs | Optional inputs | Constraints |
|---|---|---|---|
status | value: "error" | "ok" | — | Closed enum; any other value is rejected with BAD_STATUS. Valid on all grains |
name | value: string | — | Matches span_name; valid on all grains |
model | value: string | — | Span grain |
cost | At least one bound | gt, gte, lt, lte | Numeric; span grain |
duration | At least one bound | gt, gte, lt, lte | Numeric nanoseconds |
judge | name: string | value: any | Raw score facts |
judged | At least one of name, prompt, type, mode | value | value alone is rejected. prompt must match [\w \-]+ |
attr | key: string | value, selector | Structured attribute lookup |
grep | field, value | — | Substring search |
rg | field, pattern | ignore_case (wire) / ignoreCase | Regex search |
tokens | field, words | — | Whole-word search; words are whitespace-split and each must match [A-Za-z0-9]+ |
| comparisons | field, value | — | eq ne gt gte lt lte; value may be a literal or col(...) |
citedBy | judge | value | Spans cited as judge evidence |
Text operations are supported on input, output, span_name, and error,
subject to the grain: error is not a span field, so text operations on it fail
with FIELD_NOT_ON_GRAIN at the spans grain. grep, rg, and tokens
reject an unsupported field at construction time, not only at the server.
Boolean, relation, and hierarchy filters
allandanyrequire at least one filter.nottakes exactly one.anySpan,everySpan, andnoSpanquantify child spans.anyTrace,everyTrace, andnoTracequantify traces in a session.- A complete source query may be nested as a cross-grain filter.
descendantOfandancestorOfacceptdepth: 1(the default) ornullonly, and are valid only on the spans grain.atLeastrequires integerk >= 1;ofisspansortraces.
Aggregate relation predicates
overSpans, overTraces, and overScores compare an aggregate with a
numeric threshold through eq|ne|gt|gte|lt|lte.
The aggregate object is:
{ "func": "count" }or:
{ "func": "sum", "field": "cost" }func is count, count_distinct, sum, avg, min, or max.
field is required except for count. overScores does not accept where;
filter the outer grain instead. overScores also aggregates over the scores
relation, so it accepts only that relation's own fields, not arbitrary grain
fields — an unsupported field fails with BAD_FIELD.
Expressions
Expressions are values used by derive and summarize, not root filters.
col(name: string): ColExpr
aggExpr(options: { func; field?; q?; per?; where? }): AggExpr
arith(fn: "div" | "mul" | "add" | "sub", left: ExprInput, right: ExprInput): ArithExpr
bucket(field: string, every: string): BucketExprThe table below gives the canonical JSON each constructor emits. The op values
are language-neutral and always snake_case, regardless of the constructor name.
| Constructor | Emitted JSON | Rules |
|---|---|---|
col | {"op":"col","name":"cost"} | References a current pipeline column |
aggExpr | {"op":"agg_expr","func":"sum","field":"cost","per":"trace","where":...} | See aggregate-expression rules below |
arith | {"op":"arith","fn":"div","left":...,"right":...} | fn: div mul add sub; operands are expressions or numbers |
bucket | {"op":"bucket","field":"timestamp","every":"1d"} | Valid only as a summarize grouping key; produces bucket |
Aggregate expressions support count, count_distinct, sum, avg,
min, max, and quantile. All except count require field.
quantile requires q with 0 < q < 1 and does not support where.
q is rejected for non-quantile functions. where uses the narrow
pipeline stage-filter grammar. per creates a
per-group window aggregate.
Nested arith expressions are capped at 8 levels inside a single
derive or summarize output; the limit counts arithmetic nesting only and does
not descend into aggregate operands. Boolean values are not numeric expression
literals.