AI Steps and Custom Code
Drop intelligence into any workflow: Generate Text for free-form output, Generate Object for typed structured data, and Execute JS Code when you need full control over your previous steps' results.
Most steps in an agent do one concrete thing — send, fetch, create. Two kinds of step are different: they add judgment and flexibility. These are the AI nodes and the custom-code node, and they're what take an agent from "moves data around" to "actually reasons about it."
Generate Text
The Generate Text node takes a prompt and returns written output. The prompt can include outputs from earlier steps, so it's grounded in your agent's real data rather than generic filler.
Reach for it when you want natural language out:
- Summarize a scraped article or a long email thread
- Draft a reply, a release note, or a customer message
- Rewrite, translate, or reformat text from a previous step
Generate Object: structured, typed output
Free text is great for humans; the rest of your workflow usually wants structured data. The Generate Object node lets you define an output shape — a set of named fields, each typed as string, number, or true/false — and the AI returns data that matches it.
That matters because the result slots straight into the steps that follow. Classify an email into { category, isUrgent, summary } and you can branch on isUrgent with an If/Else, write category to a sheet, and drop summary into a Telegram message — no fragile text parsing in between.
Use Generate Object whenever the AI's answer needs to be used by another step rather than just read by a person.
Execute JS Code
Sometimes you need exact control. The Execute JS Code node runs JavaScript you write, with every previous step's output handed to you in a steps array. Whatever you return becomes this step's output, available to everything downstream.
// 'steps' holds the outputs of previous steps, in order.
const contacts = steps[1].output;
const active = contacts.filter((c) => c.status === "active");
return {
count: active.length,
emails: active.map((c) => c.email),
};
It's the escape hatch for the things a fixed action can't express: reshaping data, custom filtering and math, merging results from several steps, or building exactly the payload the next step expects.
When to use which
- Need words for a person to read? Generate Text.
- Need fields for another step to use? Generate Object.
- Need precise, deterministic transformation of your data? Execute JS Code.
Mix them freely. A common pattern is Generate Object to extract structure, then Execute JS Code to reshape it, then a plain action to deliver it — intelligence and precision, each doing the part it's best at. From there it's all about where the data goes, which is the integration library.
One short email. Every Friday.
New posts, product updates, and the most useful agent recipes from the community — handpicked by our team. No fluff, unsubscribe anytime.
No spam. Read by 12,000+ builders and operators.