Skip to main content

CEL Functions Reference

Complete reference for all built-in functions available in AutoTalk CEL expressions. Functions are organized by category.


Core

get(obj, path, default?)

Safely access a nested property via a dotted path.

get(client, "address.city")                  // "São Paulo"
get(client, "address.zip", "00000-000") // returns default if missing
get(null, "name") // null
get(step(0), "data.results.0.title") // deep path with array index
ParamTypeDescription
objanyObject to access (null-safe)
pathstringDotted path (e.g. "a.b.c")
defaultanyValue returned if path missing (default: null)

has(obj, path?)

Check if a value or nested path exists and is not null/undefined.

has(client, "email")        // true if client.email is set
has(myVar) // true if myVar is not null/undefined
has(obj, "a.b.c") // true if full path resolves to non-null

coalesce(...vals)

Return the first non-null, non-undefined value. Variadic (accepts 2+ arguments).

coalesce(client.nickname, client.name, "Guest")   // first non-null wins
coalesce(0, 42) // 0 (not null!)
coalesce(false, true) // false (not null!)
coalesce("", "fallback") // "" (not null!)
Null-check semantics

coalesce() only skips null and undefined. Values like 0, false, and "" are valid and returned.

now()

Returns the current date/time.

now()                                    // current datetime
format_datetime(now(), "YYYY-MM-DD") // "2024-01-15"

present(val)

Check if a value is meaningfully present. Returns false for null, undefined, empty/whitespace strings, and empty arrays. Numbers and booleans are always present.

present(client.email)         // true if non-empty string
present("") // false
present(" ") // false (whitespace only)
present(0) // true
present([]) // false
present([1, 2]) // true
Replaces verbose patterns

present(x) replaces the common pattern size(trim(coalesce(x, ""))) > 0.

blank(val)

Inverse of present(). Returns true for null, undefined, empty/whitespace strings, and empty arrays.

blank(client.email)           // true if null or empty
blank("hello") // false
blank(0) // false

Utility

pluck(arr, path)

Extract a property from each object in an array.

pluck(clients, "name")                     // ["Alice", "Bob", "Carol"]
pluck(tools, "tool.function.name") // deep path supported

slice(arr, start, end?)

Safely slice an array. Returns [] for non-array inputs. Supports negative indices.

slice(results, 0, 5)         // first 5 items
slice(results, -3) // last 3 items
slice(results, 1, -1) // all except first and last
slice(null, 0, 2) // [] (safe for non-arrays)

defaults(obj, fallbacks)

Merge fallback values into an object for keys that are null/undefined. Shallow merge.

defaults(response, {"status": "unknown", "retryable": false})
// Fills in status and retryable only if they are null/undefined in response
Null-check semantics

Like coalesce(), only null/undefined values are replaced. 0, false, and "" are kept.

url_params(base, params)

Build a URL with query parameters. Skips null and empty values. Auto-encodes.

url_params("https://api.example.com/search", {"q": query, "page": 1, "lang": null})
// "https://api.example.com/search?q=hello&page=1" (lang skipped)

truncate(str, maxLen, suffix?)

Truncate a string to a maximum length with an optional suffix.

truncate("Hello World", 5)              // "Hello"
truncate("Hello World", 8, "...") // "Hello..."
truncate(null, 10) // "" (null-safe)
truncate("Hi", 100) // "Hi" (no truncation needed)
ParamTypeDescription
stranyValue to truncate (coerced to string, null returns "")
maxLennumberMaximum length of result (including suffix)
suffixstringAppended when truncated (default: "")
tip

The suffix is included within maxLen: truncate("Hello World", 8, "...") returns "Hello..." (8 chars).

tpl(template, vars)

Simple string interpolation. Replaces {key} placeholders with values from an object.

tpl("Hello {name}!", {"name": "Alice"})                    // "Hello Alice!"
tpl("*{title}*\n{domain}\n{url}", article) // formatted article text
tpl("{address.city}, {address.country}", client) // dotted path support
tpl("Hi {name}", {"name": null}) // "Hi " (null → empty)
ParamTypeDescription
templatestringTemplate string with {key} placeholders
varsobjectObject with values to interpolate

join_present(separator, ...values)

Join values with a separator, skipping blank values. Uses the same rules as present(): null, empty/whitespace strings, and empty arrays are skipped. 0 and false are kept.

join_present(", ", "Alice", "Bob", "Carol")       // "Alice, Bob, Carol"
join_present(" - ", title, null, author) // "Title - Author" (null skipped)
join_present(" ", "Hello", "", "World") // "Hello World" (empty skipped)
join_present(" | ", 0, false, "text") // "0 | false | text" (0/false kept)
Replaces conditional concatenation

join_present(" - ", prefix, text) replaces the pattern (present(prefix) ? prefix + " - " : "") + text.

encode_uri(str)

URL-encode a string.

encode_uri("hello world")    // "hello%20world"

format_currency(n, currency, locale?)

Format a number as currency.

format_currency(1234.5, "USD", "en-US")    // "$1,234.50"
format_currency(99.9, "BRL", "pt-BR") // "R$ 99,90"

String

CEL includes built-in string functions. Most work as both receiver-style and function-style:

"hello".contains("ell")      // true (receiver-style)
contains("hello", "ell") // true (function-style)
FunctionDescriptionExample
contains(str, sub)Check if string contains substring"hello".contains("ell")
startsWith(str, prefix)Check prefix"hello".startsWith("he")
endsWith(str, suffix)Check suffix"hello".endsWith("lo")
split(str, sep)Split into arraysplit("a,b,c", ",")["a","b","c"]
lowerAscii(str)LowercaselowerAscii("HELLO")"hello"
upperAscii(str)UppercaseupperAscii("hello")"HELLO"
trim(str)Trim whitespacetrim(" hi ")"hi"
substring(str, start, end?)Extract substringsubstring("hello", 1, 4)"ell"
replace(str, old, new)Replace occurrencesreplace("aab", "a", "x")"xxb"
indexOf(str, sub)First index of substringindexOf("hello", "l")2
lastIndexOf(str, sub)Last index of substringlastIndexOf("hello", "l")3
charAt(str, index)Character at indexcharAt("hello", 0)"h"
join(list, sep?)Join array to stringjoin(["a","b"], ",")"a,b"

Math

FunctionDescriptionExample
math_add(a, b)Addmath_add(5, 3)8
math_subtract(a, b)Subtractmath_subtract(10, 3)7
math_multiply(a, b)Multiplymath_multiply(4, 3)12
math_divide(a, b)Dividemath_divide(10, 3)3.333...
math_round(n, decimals?)Roundmath_round(3.456, 2)3.46
math_floor(n)Floormath_floor(3.7)3
math_ceil(n)Ceilingmath_ceil(3.1)4
math_abs(n)Absolute valuemath_abs(-5)5
math_pow(base, exp)Powermath_pow(2, 3)8
math_sqrt(n)Square rootmath_sqrt(16)4
math_max(arr)Maximummath_max([1,5,3])5
math_min(arr)Minimummath_min([1,5,3])1
math_mean(arr)Averagemath_mean([1,2,3])2
math_median(arr)Medianmath_median([1,2,10])2
math_clamp(val, min, max)Constrain to rangemath_clamp(15, 0, 10)10

math_clamp(val, min, max)

Constrain a number within a range.

math_clamp(page, 1, 100)     // ensure page is between 1 and 100
math_clamp(-5, 0, 10) // 0 (below min)
math_clamp(15, 0, 10) // 10 (above max)

DateTime

FunctionDescription
now()Current date/time
format_datetime(d, fmt, tz?)Format a datetime. Formats: "DD/MM/YYYY", "YYYY-MM-DD HH:mm:ss", "HH:mm"
add_datetime(d, n, unit)Add time. Units: "years", "months", "days", "hours", "minutes", "seconds"
diff_datetime(d1, d2, unit)Difference between two datetimes
zoned_datetime(d, tz)Convert to timezone
is_before(d1, d2)d1 before d2?
is_after(d1, d2)d1 after d2?
is_between(d, start, end)d between start and end?

JSON

FunctionDescription
json_parse(str)Parse JSON string to object
json_stringify(obj)Serialize object to JSON string

BSON / ObjectId

FunctionDescription
object_id()Generate new ObjectId string
object_id_is_valid(id)Check if string is valid ObjectId
object_id_to_string(id)Convert ObjectId to string

Workflow-Specific

These functions are available only in workflow and agent expressions (not in form CEL).

step(N)

Access output from workflow step N (0-indexed).

step(0)                      // full step output object
step(0).data // the step's data payload
step(0).status // HTTP status code (for HTTP steps)

step_ok(N)

Check if step N completed successfully. Returns true when executionContext.status is "completed" AND HTTP status is 200 (or null for non-HTTP steps).

// Before: verbose
get(step(0), "executionContext.status") == "completed" && (get(step(0), "status") == null || get(step(0), "status") == 200)

// After: one function call
step_ok(0)

step_data(N, path?, default?)

Get data from step N at an optional dotted path. Returns default (or null) if missing.

// Before
get(step(0), "data.title", null)

// After
step_data(0, "title")
step_data(0, "results.0.name", "Unknown")
step_data(1, "choices.0.message.content")

step_error(N)

Get error info from a failed step. Returns {code, user_message, retryable} or null.

// Before
coalesce(get(step(0), "executionContext.safeError.code"), "UNKNOWN")

// After
step_error(0) // {code: "TIMEOUT", user_message: "...", retryable: true}
get(step_error(0), "code", "UNKNOWN") // "TIMEOUT"

step_has_content(N, path)

Check if step N completed successfully AND has present (non-null, non-empty) data at the given path. Combines step_ok(N) && present(step_data(N, path)) into one call.

// Before: two checks
step_ok(0) && present(step_data(0, "articles"))

// After: one function call
step_has_content(0, "articles")

getContext()

Get the workflow execution context object.

getTool(name)

Get a tool result from context.

getRoot()

Get the root workflow context.