Inputs, outputs, and environment
A code tool has four parts: the inputs it receives, the environment variables it reads for configuration and secrets, the outputs it returns, and the code that produces the result. The inputs, environment variables, and outputs are defined when the tool is created and referenced by name in the code.
Inputs
Each input to a code tool comes from one of two sources:
- Supplied by the AI Agent: the Agent works the value out from the conversation. Agent-supplied inputs can be text, a number, true/false, or a list.
- Linked to a variable: the value is read from a saved variable. An object must be linked to a variable; the Agent cannot supply one directly.
Define each input the tool needs, along with its source and type. The Agent only fills in the inputs marked as Agent-supplied.
Environment variables
Environment variables hold configuration and secrets, for example a base URL or an API key. Keeping these outside the code means the same tool can point at different systems or credentials without rewriting it.
Read them in code with os.getenv("NAME") or os.environ["NAME"] after import os. Only the variables you declare here are exposed; nothing from Ada’s own environment is reachable.
Secrets are stored redacted. Once saved, a secret’s value is not shown again in the dashboard.
Outputs
Each output is a field the tool returns. For every output, choose how it is used:
- Exposed to the AI Agent: the Agent can use the value in its replies.
- Saved to a variable: the value is written to a variable for later steps to read.
An output can be exposed to the Agent, saved to a variable, or both. Declare one output per field so each value is addressed on its own.
The code
The tool returns the value of its last expression: whatever the final line evaluates to becomes the result. You don’t wrap it in a function or write a return. Your inputs are available as variables by name, and you call the available functions below directly.
Supported Python
The code runs on a sandboxed Python interpreter — a restricted subset, not full Python. Here is exactly what’s available.
You can use
- Variables, arithmetic, string operations, and f-strings (including format specs like
f"{price:.2f}"). - Conditionals (
if), loops (for/while), comprehensions,try/except, and your owndefandlambdafunctions. - Import these standard-library modules as usual:
json,re,datetime,math,os,pathlib,sys, andtyping. (pathlibcan only build paths; reading a file is blocked.) - The current date and time: after
from datetime import datetime, date,datetime.now()anddate.today()return the time in your AI Agent’s configured timezone.
You can’t use
- Any other import. No
requests,random,collections,itertools, and so on. A disallowedimportfails when the tool runs, not when you save it. Common gaps (hashing, Base64, URL-encoding, UUIDs) are covered by the built-in functions instead. - Classes, generators, and
del. Noclassdefinitions (which also rules out@dataclassand custom exception types), no generators (yield), and nodelstatement. These are caught when you save. eval,exec,openand file access,input, and dynamic tricks likeglobals().%or.format()string formatting. Use f-strings instead.
The result
The result is the tool’s last expression, and it must be a JSON value: text, a number, true/false, a list, or an object with text keys, not a file or an image. A few common Python types aren’t JSON and must be converted before you return them: a datetime (call .isoformat()), a set or tuple (wrap in list(...)), or bytes (decode it first). Returning nothing (None) counts as no result.
To make a network request, read an environment variable, or read and write variables, use the built-in functions below rather than a library. For the full sandbox limits, see Limits and best practices.
Available functions
Ada provides these functions directly in your code, no import needed.
fetch — make an HTTP request
fetch(method, url, headers=None, body=None, timeout=None) returns an object with status_code, headers, and body. The body is a string, so parse it with json.loads if it’s JSON. Requests reach only the domains on your allowed-domains list (plus your own Ada instance); a blocked or failed request raises an error you can catch. Redirects aren’t followed, so a request to a redirecting URL returns the 3xx response, not the final page. Per run: up to 10 requests, a 1 MB response each, and about 60 seconds of network time.
get_variable and set_variable — read and write variables
get_variable(name) returns a saved variable’s current value, and raises if it doesn’t exist. set_variable(name, value) saves a value, applied only if the run succeeds. Sensitive-scoped variables can’t be read or written from code.
Utilities — hashing, encoding, and IDs
Common helpers that would otherwise need a library, available directly (no import):
uuid4()— a random UUID string.sha256(text)andhmac_sha256(key, text)— hex digests.b64encode(text)andb64decode(text)— Base64 encode and decode.quote(text)andurlencode(mapping)— URL-encode a single value, or a set of query parameters.
log — write to the run log
log(...) (and print(...)) adds a line to the tool’s run log for debugging. Logs show in the conversation’s run detail, have secrets redacted, and are never shown to the AI Agent.
Voice capture
For voice-enabled AI Agents, code-tool inputs support the same voice capture settings as API tools (speech, keypad, or SMS), along with confirmation before the value is used. This lets an Agent collect an input reliably over a voice call.