Skip to main content
Devset’s built-in functions let you generate dynamic values, perform calculations, and evaluate conditions directly inside your workflow and stage definitions. You call a function by wrapping it in a { "$fn": "..." } expression — anywhere a DslValue is accepted, such as a set field, a state mutation, the emit condition, or a repeat guard. Functions evaluate fresh on every stage execution, so each run produces independent results.

How to Use Functions

Wrap any function call in a $fn expression object:
{ "$fn": "uuid()" }
{ "$fn": "int(10, 500)" }
{ "$fn": "choice(PENDING,ACTIVE,CLOSED)" }
Assign the result to a payload field inside a stage’s set block:
"set": {
  "id":        { "$fn": "uuid()" },
  "amount":    { "$fn": "int(1, 1000)" },
  "status":    { "$fn": "choice(PENDING,ACTIVE)" },
  "createdAt": { "$fn": "now()" }
}
Or use a function as a condition in emit, repeatWhile, or repeatUntil:
"emit": { "$fn": "lt(state.order.count, 100)" }

Referencing Values in Arguments

Function arguments can be more than literals. You have two ways to pass live values into a function call: Payload path reference — prefix a field name with . to read from the current stage’s resolved payload:
{ "$fn": "add(state.order.total, .amount)" }
Here .amount reads the amount field that was assigned earlier in the same stage’s set block. State reference — use state. followed by a dot-notation path to read from workflow state:
{ "$fn": "add(state.order.count, 1)" }
You can nest function calls freely. The inner call is evaluated first and its result is passed as an argument to the outer call:
{ "$fn": "add(state.count, int(1, 5))" }
This adds a random integer between 1 and 5 to the current count on every execution.

Generation Functions

Use these functions to produce random values for payload fields.

uuid()

Signature: uuid() Generates a random UUID v4 string. Use this for unique identifiers such as message IDs, order IDs, or correlation IDs.
{ "$fn": "uuid()" }
Example output: "a3f4c1d2-7e8b-4f09-b1c3-0e2a5d6f8901"

string()

Signature: string() Generates a random alphanumeric string. Useful when you need a short opaque token or reference code.
{ "$fn": "string()" }

bit()

Signature: bit() Returns a random integer of either 0 or 1. Useful for binary flags or simple on/off fields.
{ "$fn": "bit()" }

bool() / boolean()

Signature: bool() or boolean() Returns a random true or false boolean value. Both names are equivalent.
{ "$fn": "bool()" }

int(min, max)

Signature: int(min, max) Returns a random integer in the inclusive range [min, max]. Both arguments must be integer literals or path references that resolve to integers.
ArgumentDescription
minLower bound (inclusive)
maxUpper bound (inclusive)
{ "$fn": "int(10, 500)" }
Example: Generate a price between 10 and 500.

long(min, max)

Signature: long(min, max) Returns a random long integer in the inclusive range [min, max]. Use this instead of int when you need values outside the 32-bit integer range — for example large Unix timestamps or database record IDs.
ArgumentDescription
minLower bound (inclusive)
maxUpper bound (inclusive)
{ "$fn": "long(1000000000000, 9999999999999)" }

Timestamp Functions

Use these functions to capture the current time in various formats.

now()

Signature: now() Returns the current wall-clock time as an ISO-8601 string.
{ "$fn": "now()" }
Example output: "2024-06-15T10:23:44.512Z"

nows()

Signature: nows() Returns the current time as a Unix timestamp in seconds (integer).
{ "$fn": "nows()" }
Example output: 1718447024

nowms()

Signature: nowms() Returns the current time as a Unix timestamp in milliseconds (integer). Useful for high-resolution timing fields or when your consumers expect millisecond-precision epoch values.
{ "$fn": "nowms()" }
Example output: 1718447024512

Choice Functions

Use these functions to pick values from a predefined set, either uniformly or with weighted probabilities.

choice(v1, v2, ...)

Signature: choice(v1, v2, ...) Picks one value from the list with equal probability. Pass any number of comma-separated values. Values do not need to be quoted.
{ "$fn": "choice(PENDING,ACTIVE,CLOSED)" }
Each call returns one of "PENDING", "ACTIVE", or "CLOSED" with roughly equal frequency.

choiceWeighted(v1:w1, v2:w2, ...)

Signature: choiceWeighted(v1:w1, v2:w2, ...) Picks one value from the list using the specified weights. Each entry is written as value:weight where weight is a positive integer. Higher weights make a value more likely to be chosen. Weights do not need to sum to 100 — they are relative to each other.
{ "$fn": "choiceWeighted(ACTIVE:70,CLOSED:20,PENDING:10)" }
In this example, "ACTIVE" is returned 70% of the time, "CLOSED" 20%, and "PENDING" 10%.
Use choiceWeighted when you want to model realistic distributions — for example, most orders being active rather than pending or closed.

Math Functions

Use these functions to compute derived numeric values, typically for maintaining running totals or calculating metrics in workflow state.

add(a, b)

Signature: add(a, b) Returns a + b. Both arguments can be literals, path references, state references, or nested function calls.
{ "$fn": "add(state.order.total, .amount)" }
Adds the current stage’s amount to the running order.total in state.

sub(a, b)

Signature: sub(a, b) Returns a - b.
{ "$fn": "sub(state.budget, .cost)" }

percent(value, total)

Signature: percent(value, total) Returns (value / total) * 100. Use this to compute percentage metrics — for example the proportion of high-value orders in a run.
ArgumentDescription
valueThe numerator
totalThe denominator
{ "$fn": "percent(state.highValue.count, state.order.count)" }

Comparison Functions

Comparison functions return a boolean (true or false) and are designed for use in emit, repeatWhile, and repeatUntil expressions. You can also use them anywhere else a DslValue is accepted.

lt(a, b) — Less Than

Returns true if a < b.
"emit": { "$fn": "lt(state.order.count, 100)" }
Emit only while the order count is below 100.

lte(a, b) — Less Than or Equal

Returns true if a ≤ b.
"repeatWhile": { "$fn": "lte(state.retries, 5)" }

gt(a, b) — Greater Than

Returns true if a > b.
{ "$fn": "gt(.amount, 200)" }

gte(a, b) — Greater Than or Equal

Returns true if a ≥ b.
"repeatUntil": { "$fn": "gte(state.retries, 3)" }

eq(a, b) — Equal

Returns true if a == b.
"emit": { "$fn": "eq(.status, ACTIVE)" }

neq(a, b) — Not Equal

Returns true if a != b.
"emit": { "$fn": "neq(.status, CANCELLED)" }

  • Stage Fields — how to use $fn expressions in set, state, emit, repeatWhile, and repeatUntil.
  • Workflow DSL — top-level workflow structure including the state object that function arguments reference.