Writing a Code Action
Create an Action in the dashboard and choose the Code backend. Default-export a function;defineAction from the SDK adds typing and an authenticated client:
inputs— the Action’s declared inputs, already validated against its input schemaconfig— your organization’s configuration variables (for API keys and settings)client— the Simple AI SDK, authenticated for your organization automatically; you never handle an API key
result — for example {{ result.plan }}.
Steering the conversation
A code action invoked from a workflow can decide where the conversation goes next. Callworkflow.transitionTo with the name of the node to run:
nodeName— the node to run next, exactly as it is named in the Agent. Any node in the workflow is reachable; you do not need an edge from the node that invoked the action.message— optional. A short sentence the agent speaks as it moves.reason— optional. Recorded with the transition on the call.
transitionTo returns normally: it records where to go next, and the rest of your handler still runs. A transition comes in addition to the result, so the example above both maps plan to its outputs and moves the conversation. Calling it more than once keeps the last request, and an action that throws transitions nowhere. If the named node does not exist in the workflow, the transition is logged and ignored, and the agent follows its own edges instead.
Capabilities
Code actions run in more places than workflows — per-turn actions, automatic before/after-call actions, and data sync all execute the same code, but there is no live conversation to steer. Each invocation states what it allows, and your handler reads it asmetadata.capabilities:
WORKFLOW_TRANSITION is granted when the action runs from a workflow — as an action node or an agent tool call. Calling transitionTo without it fails the action with a MissingCapabilityError, so check metadata.capabilities first if the same action also runs outside workflows.
Rules and Limits
- TypeScript or JavaScript in the Cloudflare Workers runtime. Use standard web APIs such as
fetch,Request, andResponse; Node.js APIs are not available. - The only importable package is
@simple-ai-lab/sdk, which is bundled when you save. - Timeout: configurable per action, 1–60 seconds (default 30). Voice conversations feel best well under 10 seconds — configure filler speech on the agent for longer actions.
- Network requests: up to 100 subrequests per execution.
- Result size: the returned value must serialize to JSON of at most 1 MB.
- Logs:
console.log/console.erroroutput is captured and shown in test runs and call transcripts — it never pollutes the result. - Each execution runs in a fresh Worker isolate; nothing persists between runs. Persist state in custom data instead.
Testing
The Action editor’s test panel runs your code in a real Worker isolate: fill in sample inputs, press Run test, and inspect the returned value (click fields to map them as outputs), stdout/stderr logs, and execution timings. Syntax errors are rejected when you save; runtime errors surface in the test result with the thrown error’s name and message. A test run has no conversation attached, so it grants no capabilities: an action that reachesworkflow.transitionTo fails there with MissingCapabilityError. Guard the call with a metadata.capabilities check to keep the rest of the action testable from the editor, and exercise the transition itself on a test call.