The Code function (type: "code") runs JavaScript you write, in a sandbox on the Tried API. Use it for small logic that does not justify hosting an endpoint: date maths, formatting, routing decisions, or a quick call to a public API with fetch.
How it runs#
The code is the body of an async function. Whatever it returns is the result. Three values are in scope:
| Name | Contents |
|---|---|
args |
The arguments the LLM passed, shaped by your parameters schema |
dv |
All dynamic variables of the call as strings (defaults, request variables, collected values, system variables such as current_time) |
metadata |
The call's metadata object |
fetch(url, init) is available and returns an object with status, ok, headers, text() and json(). console.log output is captured by the sandbox (up to 200 lines) but is not passed to the LLM.
// args, dv (dynamic variables) and metadata are in scope
const total = Number(args.items) * Number(dv.unit_price || 0);
const res = await fetch(`https://api.example.com/postcodes/${encodeURIComponent(args.postcode)}`);
const area = res.ok ? (await res.json()).region : "unknown";
return { total, area, eligible: total > 100 && area !== "unknown" };The returned value is serialised to JSON, cut to 15,000 characters and handed to the LLM. With Speak after execution on (the default), the agent then replies.
Configure in the dashboard#
- Open the agent, expand Functions, click Add and choose Code.
- Name and Description. The default description is "Run JavaScript and return a result."
- JavaScript: your code. Save is disabled while it is empty.
- Parameters: the arguments the LLM fills in (Form or JSON schema).
- Timeout (seconds): 5 to 60. Default 10.
- Response variables: name to JSON path, for example
totalto$.total. - While it runs options, then Save.
Fields#
| Field | Type | Default | Description |
|---|---|---|---|
type |
"code" |
||
name, description |
string | ||
code |
string, up to 20,000 characters | Body of an async function | |
parameters |
JSON schema object | Arguments for the LLM | |
timeout_ms |
integer, 1,000 to 60,000 | 10,000 | Total run time |
response_variables |
object of name to JSON path | Saved from the returned value | |
speak_during_execution, speak_after_execution, execution_message_description |
See execution options |
Sandbox limits#
| Limit | Value |
|---|---|
| Engine | QuickJS compiled to WebAssembly, no access to the host process, file system or environment |
| Memory | 32 MB |
| Stack | 1 MB |
| Run time | timeout_ms, capped by the API setting CODE_SANDBOX_MAX_MS (default 60,000 ms) |
fetch |
http and https only, 15 s per request, response body cut to 200,000 characters |
fetch destinations |
Private network addresses (10/8, 127/8, 0/8, 169.254/16, 172.16/12, 192.168/16, 100.64/10, IPv6 loopback, fc, fd and fe80 prefixes) are refused |
| Result | 15,000 characters of JSON |
SANDBOX_ALLOW_PRIVATE_NETWORK=1 on the API lifts the private network check for local development.
Errors#
| Situation | Text the LLM gets |
|---|---|
| Your code throws or a promise rejects | Error: <message> |
| Syntax error | Error: <message> |
| Over the time limit | Error: Code timed out after <ms> ms while waiting on a promise. A busy loop is stopped by the interrupt handler and returns an Error: interrupted style message |
| Code ends with a pending promise and no return | Error: Code finished without a result (unresolved promise) |
| API unreachable | Error: code sandbox unreachable: ... |
return nothing and the result is null.
Response variables#
response_variables reads from the returned value with the same JSON path syntax as custom functions ($.a.b[0]). With the example above, {"eligible": "$.eligible"} saves {{eligible}} as true or false for the rest of the call.
In conversation flows#
The code node runs code at a fixed step without an LLM call, stores result fields as variables and then follows equation edges. It is the usual way to branch on computed values.
Gotchas#
- Node.js APIs such as
require,processandBufferare not available. Keep code self-contained. dvvalues are strings. Convert withNumber()before maths.- The sandbox runs on the API, so
fetchgoes out from the API host, not the voice worker.