Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt

Use this file to discover all available pages before exploring further.

How Formulas Work

KaireonAI includes a safe, sandboxed formula engine for computing personalized values at decision time. The engine follows a strict pipeline:
  1. Tokenizer — Breaks the formula string into tokens (numbers, strings, identifiers, operators, punctuation)
  2. Parser — Recursive-descent parser builds an Abstract Syntax Tree (AST) from the token stream
  3. Evaluator — Walks the AST and computes the result structurally
The engine uses no eval, Function, or vm — all evaluation is structural, making it safe by design. Any formula that fails to parse or evaluate returns null rather than throwing an error. Formulas are defined on computed custom fields within Categories. At decision time, the Recommend API evaluates each formula per candidate offer and merges the results into the response.

Variable Namespaces

Formulas can reference three namespaces of variables:
NamespaceSourceExampleWhen Available
fieldNameOther custom field values on the offerbase_rate, offer_priceAlways — values come from the offer’s custom fields
customer.*Enriched data from schema tables via the Enrich stagecustomer.loan_amount, customer.balanceWhen an Enrich stage is configured in the Decision Flow
attributes.*Request-time attributes from the Recommend API bodyattributes.tier, attributes.channelWhen the caller passes attributes in the Recommend request
Variables are resolved as a flat key-value map. Dot notation (e.g., customer.loan_amount) is part of the identifier — the engine treats customer.loan_amount as a single variable name, not an object property access.

Operators

Arithmetic Operators

OperatorDescriptionExamplePrecedence
+Addition (numbers) or concatenation (strings)base_rate + 1.54
-Subtractionprice - discount4
*Multiplicationquantity * unit_price5
/Division (returns null on divide by zero)total / count5
%Modulo (returns null on mod by zero)index % 35
- (unary)Negation-score6

Comparison Operators

All comparison operators return 1 for true and 0 for false. String comparisons support only == and !=.
OperatorDescriptionExamplePrecedence
>Greater thancustomer.age > 183
<Less thancustomer.score < 503
>=Greater than or equalcustomer.age >= 213
<=Less than or equalbalance <= 03
==Equal (numbers or strings)attributes.tier == "gold"3
!=Not equal (numbers or strings)customer.status != "inactive"3

Precedence Summary (highest to lowest)

LevelOperators
6Unary -
5*, /, %
4+, -
3>, <, >=, <=, ==, !=
1? : (ternary)
Parentheses () override default precedence.

Functions

The engine includes six built-in functions. Each is shown below with its signature and an example use. min — returns the smaller of two numbers.
min(a, b)
min(customer.rate, 25.0)
max — returns the larger of two numbers.
max(a, b)
max(customer.score, 0)
round — rounds to the nearest integer, or to N decimal places when a second argument is supplied.
round(value)
round(value, decimals)
round(total * 0.0825, 2)
abs — returns the absolute value of a number.
abs(value)
abs(customer.balance)
coalesce — returns the first non-null argument (minimum two arguments). Result type matches the first non-null value.
coalesce(a, b, ...)
coalesce(customer.rate, base_rate, 5.0)
concat — joins all arguments as strings (minimum two arguments).
concat(a, b, ...)
concat("Hello ", customer.name)
Unknown function names return null. Functions with the wrong number of arguments also return null.

Ternary Expressions

Ternary expressions provide conditional logic:
condition ? valueIfTrue : valueIfFalse
The condition is evaluated first. A condition is truthy if it is a non-zero number or a non-empty string. A condition of 0, "", or null is falsy.
customer.age >= 21 ? "eligible" : "ineligible"
Ternary expressions can be nested using parentheses:
customer.qty > 100 ? 0.50 : (customer.qty > 50 ? 0.75 : 1.00)
If the condition evaluates to null, the entire ternary returns null.

Type Coercion

Computed fields declare an outputType of either number or text. This is a metadata hint used for validation and display — the formula engine itself returns whatever type the expression produces:
  • Arithmetic operations return numbers
  • String operations (+ on two strings, concat) return strings
  • Comparison operators always return 1 or 0 (numbers)
  • coalesce returns the type of the first non-null argument
When defining a computed field, choose the outputType that matches your formula’s expected result. The Categories API rejects any computed field that omits either a formula string or an outputType of number or text.

Error Handling

The formula engine is designed to fail gracefully. Every error condition returns null rather than throwing:
ConditionBehavior
Division by zero (10 / 0)Returns null
Modulo by zero (10 % 0)Returns null
Missing or undefined variableReturns null (use coalesce to provide a default)
null variable valueReturns null (null propagates through all operations)
Syntax error or unparseable formulaReturns null
Mismatched parenthesesReturns null
Empty formulaReturns null
Unknown function nameReturns null
Wrong argument count for a functionReturns null
Type mismatch (e.g., arithmetic on strings)Returns null
Unterminated string literalReturns null
Null propagation rule: If any operand in a binary operation is null, the entire operation returns null. This means 5 + null is null, not 5. Use coalesce to guard against missing values.

Real-World Formulas

Simple arithmetic

base_rate * 1.1
Applies a 10% markup to the offer’s base_rate custom field.

Customer data lookup

customer.balance * 0.02
Computes 2% of the customer’s balance (loaded via Enrich stage).

Request-time conditional

attributes.tier == "gold" ? 500 : 200
Returns a different reward amount based on the tier passed in the Recommend request.

Fallback with coalesce

coalesce(customer.preferred_rate, base_rate, 5.0)
Uses the customer’s preferred rate if available, falls back to the offer’s base rate, then to a hardcoded default of 5.0.

String personalization

concat("Hello ", customer.first_name)
Builds a personalized greeting from enriched customer data.

Rounded calculation

round(customer.loan_amount * base_rate / 100, 2)
Computes a monthly interest amount rounded to 2 decimal places.

Conditional discount

base_price * (1 - (customer.loyalty_years > 5 ? 0.15 : 0.05))
Applies a 15% discount for customers with more than 5 loyalty years, otherwise 5%.

Clamping with min/max

max(min(calculated_rate, 25.0), 2.5)
Ensures a rate stays within the 2.5 to 25.0 range.

Multi-variable calculation

(customer.income - customer.expenses) * risk_factor
Computes disposable income multiplied by an offer-level risk factor.

Channel-aware text

attributes.channel == "email" ? concat(customer.name, ", check out ", offer_name) : offer_name
Returns a personalized message for email, or only the offer name for other channels.

Tiered pricing with nested ternary

customer.qty > 100 ? 0.50 : (customer.qty > 50 ? 0.75 : 1.00)
Three-tier pricing: high volume at 0.50, medium at 0.75, standard at 1.00.

Scoring with null safety

coalesce(customer.score, 0) * offer.weight + coalesce(customer.bonus, 0)
Builds a weighted score with safe defaults for missing values.

Validation

UI Validation

The Business Hierarchy page (Category editor) includes a Validate button next to each computed field. Clicking it parses the formula in place and returns either a green check or a red error message describing exactly what failed (unbalanced parentheses, unknown function, missing operand, and so on), so authors can fix mistakes before saving.

API Validation

The Categories API enforces the same rules on every create and update request:
  • Every field with type: "computed" must have a non-empty formula string
  • Every computed field must have an outputType of either "number" or "text"
Missing either property is rejected with a 400 Bad Request and a validation error describing which field failed.

Business Hierarchy

Define Categories with computed custom fields

Decision Flows

Configure Enrich and Compute stages in flows

Composable Pipeline

V2 pipeline architecture with compute nodes