Judgment Labs Logo

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

OperationRequired inputsOptional inputsConstraints
statusvalue: "error" | "ok"Closed enum; any other value is rejected with BAD_STATUS. Valid on all grains
namevalue: stringMatches span_name; valid on all grains
modelvalue: stringSpan grain
costAt least one boundgt, gte, lt, lteNumeric; span grain
durationAt least one boundgt, gte, lt, lteNumeric nanoseconds
judgename: stringvalue: anyRaw score facts
judgedAt least one of name, prompt, type, modevaluevalue alone is rejected. prompt must match [\w \-]+
attrkey: stringvalue, selectorStructured attribute lookup
grepfield, valueSubstring search
rgfield, patternignore_case (wire) / ignoreCaseRegex search
tokensfield, wordsWhole-word search; words are whitespace-split and each must match [A-Za-z0-9]+
comparisonsfield, valueeq ne gt gte lt lte; value may be a literal or col(...)
citedByjudgevalueSpans 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

  • all and any require at least one filter. not takes exactly one.
  • anySpan, everySpan, and noSpan quantify child spans.
  • anyTrace, everyTrace, and noTrace quantify traces in a session.
  • A complete source query may be nested as a cross-grain filter.
  • descendantOf and ancestorOf accept depth: 1 (the default) or null only, and are valid only on the spans grain.
  • atLeast requires integer k >= 1; of is spans or traces.

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): BucketExpr

The table below gives the canonical JSON each constructor emits. The op values are language-neutral and always snake_case, regardless of the constructor name.

ConstructorEmitted JSONRules
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.