Reference

Function

The Function block runs your own JavaScript or Python code as one step of a workflow. Use it to reshape a value, run a calculation, or add logic no other block covers.

Function
LanguageJavaScript
Code-
error

Configuration

Code

Your code, in JavaScript (the default) or Python — pick the language on the block. Reference an earlier output directly, with no quotes around the tag, and read an environment variable with {{VAR}}:

const data = <api.data>;
return data.items.filter((i) => i.active).map((i) => i.id);
import json
data = json.loads('<api.data>')
print(json.dumps([i["id"] for i in data["items"] if i["active"]]))

Return a value in JavaScript with return. In Python, print it as JSON to stdout with print(json.dumps(...)); the block captures stdout as the result. Your code runs in an async context, so you can await directly in JavaScript.

Outputs

OutputWhat it is
<function.result>The value your code returns (object, array, string, number, …)
<function.stdout>Anything printed with console.log() or print()

Language

JavaScript runs in a fast local sandbox, or in an E2B sandbox when your code uses import or require. Python always runs in the E2B sandbox.

JavaScriptPython
ExecutionLocal sandbox (fast), or E2B with importsAlways E2B sandbox
Return a valuereturn { … }print(json.dumps({ … }))
HTTP requestsfetch() built-inrequests or httpx
Best forquick transforms, JSONdata science, charts, complex math

Python requires E2B. It is enabled by default on sim.ai; on a self-hosted instance, enable E2B to see Python in the language dropdown. Any figures you generate are captured as images automatically.

Beyond the Python standard library, the sandbox ships E2B's data-science stack plus a few Sim additions:

  • Data: pandas, numpy, scipy, xarray, numba, joblib
  • ML and NLP: scikit-learn, gensim, nltk, spacy, textblob
  • Plots and images: matplotlib, seaborn, plotly, bokeh, pillow, opencv-python, scikit-image, imageio
  • Audio: librosa, soundfile
  • Web and files: requests, aiohttp, beautifulsoup4, openpyxl, xlrd, python-docx, orjson
  • Math and testing: sympy, pytest
  • Sim additions: awscli, yq, csvkit

Examples

Reshape an API response

The Function reads <api.data>, returns just the field the rest of the workflow needs, and exposes it as <extract.result>.

Validate input before writing

The Function sanitizes the form input and returns the clean value, which the API block sends as its body.

A worked example: loyalty score

loyalty-calculator.js
const { purchaseHistory, accountAge, supportTickets } = <agent>;

const totalSpent = purchaseHistory.reduce((sum, p) => sum + p.amount, 0);
const purchaseFrequency = purchaseHistory.length / (accountAge / 365);
const ticketRatio = supportTickets.resolved / supportTickets.total;

const spendScore = Math.min((totalSpent / 1000) * 30, 30);
const frequencyScore = Math.min(purchaseFrequency * 20, 40);
const supportScore = ticketRatio * 30;
const loyaltyScore = Math.round(spendScore + frequencyScore + supportScore);

return {
  customer: <agent.name>,
  loyaltyScore,
  loyaltyTier: loyaltyScore >= 80 ? 'Platinum' : loyaltyScore >= 60 ? 'Gold' : 'Silver',
};
loyalty-calculator.py
import json

data = json.loads('<agent>')
purchase_history = data["purchaseHistory"]
account_age = data["accountAge"]
support_tickets = data["supportTickets"]

total_spent = sum(p["amount"] for p in purchase_history)
purchase_frequency = len(purchase_history) / (account_age / 365)
ticket_ratio = support_tickets["resolved"] / support_tickets["total"]

spend_score = min(total_spent / 1000 * 30, 30)
frequency_score = min(purchase_frequency * 20, 40)
support_score = ticket_ratio * 30
loyalty_score = round(spend_score + frequency_score + support_score)

tier = "Platinum" if loyalty_score >= 80 else "Gold" if loyalty_score >= 60 else "Silver"
print(json.dumps({ "customer": data["name"], "loyaltyScore": loyalty_score, "loyaltyTier": tier }))

Large inputs

Sim hands a Function block its code, parameters, and resolved references in one request, so very large values are kept by reference rather than inlined.

Prefer a narrow reference over a whole large value: use <api.data.id> instead of <api.data>. If a JavaScript function without imports does reference a whole large value, Sim rewrites it to a lazy server-side read automatically.

Files are metadata-first: reading <file.name> or <file.url> does not load the file's contents. Read content on demand with the sim.files helpers (JavaScript without imports only):

const file = <readfile.file>;
const text = await sim.files.readText(file);
const chunk = await sim.files.readTextChunk(file, { offset: 0, length: 1024 * 1024 });
const bytes = await sim.files.readBase64Chunk(file, { offset: 0, length: 1024 * 1024 });

sim.files.readText, readBase64, and the …Chunk variants stream from execution storage under memory caps. sim.values.read(ref) and sim.values.readArray(ref) read large value and array references. Chunk offset and length are byte-based, so for exact Unicode parsing prefer smaller structured references. For large generated data, write the result to a file or table with outputPath, outputSandboxPath, or outputTable instead of returning the whole payload inline.

The lazy sim.files and sim.values helpers are available only in JavaScript functions without imports. JavaScript with imports, Python, and shell do not support them yet.

Best Practices

  • Keep each function focused. One transform per block is easier to read, test, and debug.
  • Handle errors. Wrap risky code in try/catch and return a clear message, or let it throw to the error path.
  • Reference only what you need. Pull a narrow field rather than a whole large object to keep values out of the request body.
  • Use stdout to debug. console.log() and print() land in <function.stdout> and the run logs.

Common Questions

JavaScript and Python. JavaScript is the default. Python requires the E2B feature, since Python always runs in a secure E2B sandbox.
JavaScript without external imports runs in a local isolated sandbox for speed. JavaScript that uses import or require runs in E2B. Python always runs in the E2B sandbox, with or without imports.
Use angle-bracket syntax directly, like <agent.content> or <api.data>, with no quotes around the tag — Sim replaces it with the real value before execution. For environment variables, use double curly braces: {{API_KEY}}.
Two outputs: result (the return value of your code, read as <function.result>) and stdout (anything logged with console.log or print, read as <function.stdout>). Include a return statement in JavaScript, or print JSON in Python, to pass data downstream.
Yes. fetch() is available in JavaScript with async/await; libraries like axios are not, only the built-in fetch. In Python, use requests or httpx in the E2B sandbox.
Yes, a configurable execution timeout. If your code exceeds it, the run is terminated and the block reports an error. Keep this in mind for external calls or heavy processing.

On this page