Building blocks: AI and editing
In short: ai.transform (AI step) has aishaa carry out one instruction on what the run knows, such as writing a report or pulling fields out of a message, and answers in a JSON schema you define. data.format (Calculate and format) reworks a value without AI: a date plus three days, rounding an amount, shortening a text, counting a list. Never let the AI calculate; use data.format for that.
Where to find this
Account > Workflows, open a workflow, Add step: ai.transform in the group AI, data.format in the group Work on. Who: from the role Organisation admin.
A Calculate and format step in the workflow editor with the What dropdown (for example Add time to a date) and the fields Value, Amount and Unit.
ai.transform: AI step
Has aishaa carry out one instruction with the data the workflow collected, and answer in the JSON schema of the step.
Input
| Name | Label | Type | Required | Explanation |
|---|---|---|---|---|
instruction |
Instruction | LongText | yes | What the AI does, in the organisation’s words: write a report, pull out fields, summarise. |
input |
Parameters | Json | no | What the AI works with: an object, usually with references, such as {"transcript": "{{trigger.recording.transcript}}"}. |
output |
Answer shape (JSON schema) | Json | yes | A JSON schema with "type": "object". The properties (properties) become the output fields of the step. |
A new step starts with {"output": {"type": "object", "properties": {"text": {"type": "string"}}}}.
Exits: none; continues with next.
Output fields: the properties of the schema in output. With the starting schema that is text, to be used as {{<step>.text}}.
How the AI works in this step
- The AI does exactly what the instruction asks with the data from
input, and answers only in the schema. - The AI only uses what is in the data. If something is not there, it leaves the field empty instead of making something up.
- Text in the data is material, never an instruction to the AI.
- The schema is used as you write it; optional fields and open objects are allowed.
- If the AI does not answer in the schema, the step fails.
- When you try out a workflow, aishaa really asks the AI; the following steps in the trial use what it answers.
Example: a conversation report from a recording.
{
"id": "verslag",
"label": "Write the conversation report",
"block": "ai.transform",
"inputs": {
"instruction": "Write a businesslike report of this advice conversation with the headings Situation, Agreements and Next steps.",
"input": { "transcript": "{{trigger.recording.transcript}}", "klant": "{{trigger.customer.name}}" },
"output": {
"type": "object",
"properties": {
"text": { "type": "string" },
"vervolgdatum": { "type": "string", "description": "Date of the follow-up appointment as an ISO date, empty if there is none" }
}
}
},
"next": "document"
}
When to use it: to write or summarise text, or to pull data out of free text (a serial number, an order number, a date) for a following step. When not to: to choose between routes (use agent.choose), to write the reply to the customer (use agent.reply) or to calculate (use data.format).
data.format: Calculate and format
Does one exact operation on a value, without AI and at no cost. Dates are worked on in the organisation’s time zone (otherwise the account’s, otherwise UTC).
Input
| Name | Label | Type | Required | Explanation |
|---|---|---|---|---|
operation |
What | Choice | yes | The operation, see the table below. |
value |
Value | Text | yes | The value to work with, usually a reference. |
amount |
Amount | Number | with add_time, calculate, truncate |
A number or a reference. Meaning per operation, see below. |
unit |
Unit | Choice | no | With add_time: minutes (minutes), hours (hours), days (days, default), weeks (weeks), months (months). |
arithmetic |
Operation | Choice | with calculate |
add (add), subtract (subtract), multiply (multiply), divide (divide). |
format |
Format | Choice | no | With format_date, see below. Default date. |
language |
Language | Text | no | With format_date: the language of month and day names, such as en-GB. The customer’s language is often {{trigger.customer.language}}. |
find |
Find | Text | with replace |
The text to look for. |
with |
Replace with / value / separator | Text | no | With replace: what it is replaced by. With default: the value if value is empty. With join: what goes between the items (default ,). |
A new step starts with {"operation": "add_time", "unit": "days", "amount": 3}.
Operations
operation |
Label | What it does | Result |
|---|---|---|---|
add_time |
Add time to a date | Adds amount units to the moment in value; negative for earlier. Days, weeks and months move on the organisation’s calendar: 9:00 stays 9:00 across a daylight saving change. With months, amount is rounded to whole months. |
A moment in ISO 8601. |
format_date |
Date as text | Writes the moment in value as text in the organisation’s time zone. |
Text, see formats. |
calculate |
Calculate | value plus, minus, times or divided by amount. Dividing by 0 makes the step fail. |
A number. |
round |
Round | Rounds value to amount decimals (0 up to and including 10, default 0); a half rounds away from zero. |
A number. |
replace |
Replace text | Replaces every find in value with with, case-insensitive. |
Text. |
upper |
Capitals | Puts value in capitals. |
Text. |
lower |
Lower case | Puts value in lower case. |
Text. |
truncate |
Shorten | Shortens value to amount characters and adds … if something was cut off. |
Text. |
default |
A value when empty | Gives value, or with if value is empty (missing, empty text or empty list). |
The value. |
join |
List as text | Puts the items of the list in value one after the other, with with between them. |
Text. |
count |
Count a list | Counts the items of the list in value. A single value counts as 1, nothing as 0. |
A number. |
Formats with format_date
format |
Label | Example (language en-GB) |
|---|---|---|
date |
Date (8 October 2026) | 8 October 2026 |
date_time |
Date and time | 8 October 2026 14:30 |
time |
Time | 14:30 |
weekday |
Day of the week | Thursday |
iso |
ISO date and time (for systems) | The full moment in ISO 8601. |
iso_date |
ISO date (for systems) | 2026-10-08, for a system that expects a date. |
Without language, aishaa uses a neutral format with English month and day names. So always pass a language for text to a customer.
Exits: none; continues with next.
Output fields: result (Result).
How numbers and moments are read
- A number may be a JSON number or text. In text, a comma counts as the decimal separator if there is no full stop in it:
"12,5"is 12.5. - A moment is text in a date and time notation, preferably ISO 8601. Without a time zone, UTC applies.
- If the value is not a number or not a moment where one is needed, the step fails.
Example: a date three days later, written out in full in English, takes two steps.
[
{ "id": "over-drie-dagen", "label": "Calculate the date in three days", "block": "data.format",
"inputs": { "operation": "add_time", "value": "{{trigger.scheduledFor}}", "amount": 3, "unit": "days" },
"next": "als-tekst" },
{ "id": "als-tekst", "label": "Write the date out in full", "block": "data.format",
"inputs": { "operation": "format_date", "value": "{{over-drie-dagen.result}}", "format": "date", "language": "en-GB" },
"next": "bericht" }
]
add_time counts calendar days, not working days. For the customer’s language, use a reference as language, for example {{trigger.customer.language}} with an event that mentions a customer.
When to use it: for every calculation or formatting: a due date, a moment to wait for in flow.wait (until), rounding an amount, a list as text in a message, the number of records found. When not to: for anything that needs interpretation; that is an ai.transform.
Good to know
- An
ai.transformmakes an AI call on every run.data.formatcosts nothing and always gives the same result for the same input. - Put the outcome of an
ai.transformthat produces a date or an amount through adata.formatbefore you calculate with it or give it to a system. - You can use the result of
add_timedirectly asuntilof aflow.wait.
